Commit f1195f19 authored by Julius Athenstaedt's avatar Julius Athenstaedt Committed by Ramon Nou
Browse files

init fuse setup

parent f44a154c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -248,6 +248,13 @@ gkfs_define_option(
    DEFAULT_VALUE ON
)

# use old resolve function
gkfs_define_option(
    GKFS_BUILD_FUSE
    HELP_TEXT "Build FUSE client"
    DEFAULT_VALUE ON
)

# use old resolve function
gkfs_define_option(
    GKFS_USE_LEGACY_PATH_RESOLVE
+5 −0
Original line number Diff line number Diff line
@@ -234,6 +234,11 @@ find_package(Threads REQUIRED)
# details transparently
find_package(Filesystem REQUIRED)

find_package(PkgConfig REQUIRED)
pkg_check_modules(FUSE3 REQUIRED fuse3)
include_directories(${FUSE3_INCLUDE_DIRS})
link_directories(${FUSE3_LIBRARY_DIRS})
add_definitions(${FUSE3_CFLAGS_OTHER})

# Search for 'source-only' dependencies
###############################################################################
+173 −0
Original line number Diff line number Diff line
/*
  Copyright 2018-2025, Barcelona Supercomputing Center (BSC), Spain
  Copyright 2015-2025, Johannes Gutenberg Universitaet Mainz, Germany

  This software was partially supported by the
  EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu).

  This software was partially supported by the
  ADA-FS project under the SPPEXA project funded by the DFG.

  This software was partially supported by the
  the European Union’s Horizon 2020 JTI-EuroHPC research and
  innovation programme, by the project ADMIRE (Project ID: 956748,
  admire-eurohpc.eu)

  This project was partially promoted by the Ministry for Digital Transformation
  and the Civil Service, within the framework of the Recovery,
  Transformation and Resilience Plan - Funded by the European Union
  -NextGenerationEU.

  This file is part of GekkoFS' POSIX interface.

  GekkoFS' POSIX interface is free software: you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation, either version 3 of the License,
  or (at your option) any later version.

  GekkoFS' POSIX interface is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License
  along with GekkoFS' POSIX interface.  If not, see
  <https://www.gnu.org/licenses/>.

  SPDX-License-Identifier: LGPL-3.0-or-later
*/

#ifndef GKFS_CLIENT_FUSE_CONTEXT_HPP
#define GKFS_CLIENT_FUSE_CONTEXT_HPP

extern "C" {
#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 12)
#include <fuse3/fuse_lowlevel.h>
}

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#include <dirent.h>
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#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>

#ifdef __FreeBSD__
#include <sys/socket.h>
#include <sys/un.h>
#endif

#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
}

/*
 * Creates files on the underlying file system in response to a FUSE_MKNOD
 * operation
 */
static inline int
mknod_wrapper(int dirfd, const char* path, const char* link, int mode,
              dev_t rdev) {
    int res;

    if(S_ISREG(mode)) {
        res = openat(dirfd, path, O_CREAT | O_EXCL | O_WRONLY, mode);
        if(res >= 0)
            res = close(res);
    } else if(S_ISDIR(mode)) {
        res = mkdirat(dirfd, path, mode);
    } else if(S_ISLNK(mode) && link != NULL) {
        res = symlinkat(link, dirfd, path);
    } else if(S_ISFIFO(mode)) {
        res = mkfifoat(dirfd, path, mode);
#ifdef __FreeBSD__
    } else if(S_ISSOCK(mode)) {
        struct sockaddr_un su;
        int fd;

        if(strlen(path) >= sizeof(su.sun_path)) {
            errno = ENAMETOOLONG;
            return -1;
        }
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if(fd >= 0) {
            /*
             * We must bind the socket to the underlying file
             * system to create the socket file, even though
             * we'll never listen on this socket.
             */
            su.sun_family = AF_UNIX;
            strncpy(su.sun_path, path, sizeof(su.sun_path));
            res = bindat(dirfd, fd, (struct sockaddr*) &su, sizeof(su));
            if(res == 0)
                close(fd);
        } else {
            res = -1;
        }
#endif
    } else {
        res = mknodat(dirfd, path, mode, rdev);
    }

    return res;
}

#endif // GKFS_CLIENT_FUSE_CONTEXT_HPP
+26 −3
Original line number Diff line number Diff line
@@ -114,6 +114,25 @@ target_sources(
)
endif ()

if (GKFS_BUILD_FUSE)
add_executable(fuse_client "")
target_sources(fuse_client
    PUBLIC
    ${CMAKE_CURRENT_LIST_DIR}/fuse/fuse_client.cpp
    PRIVATE
    ${INCLUDE_DIR}/client/fuse/fuse_client.hpp
    )

target_link_libraries(fuse_client
    ${FUSE3_LIBRARIES}
    gkfs_user_lib
    )

target_include_directories(fuse_client
    PRIVATE
    ${FUSE3_INCLUDE_DIRS}
    )
endif()

if (GKFS_BUILD_USER_LIB)
target_compile_definitions(gkfs_user_lib PUBLIC BYPASS_SYSCALL ENABLE_USER)
@@ -222,6 +241,10 @@ install(
)
endif ()

if (GKFS_BUILD_FUSE)
install(TARGETS fuse_client RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif ()

install(
    TARGETS gkfs_common
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+1438 −0

File added.

Preview size limit exceeded, changes collapsed.