Resolve "mmap support"

Closes #199

Partial implementation

Merge request reports

Loading
+10 −0
Changes for include/client/gkfs_functions.hpp: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -182,6 +182,16 @@ int
gkfs_rename(const std::string& old_path, const std::string& new_path);
#endif // HAS_RENAME

// gkfs_mmap
void*
gkfs_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);

int
gkfs_munmap(void* addr, size_t length);

int
gkfs_msync(void* addr, size_t length, int flags);

} // namespace gkfs::syscall

// gkfs_getsingleserverdir is using extern "C" to demangle it for C usage
+8 −0
Changes for include/client/hooks.hpp: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -233,6 +233,14 @@ hook_fallocate(int fd, int mode, off_t offset, off_t len);
int
hook_fadvise64(int fd, off_t offset, off_t len, int advice);

void*
hook_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);

int
hook_munmap(void* addr, size_t length);

int
hook_msync(void* addr, size_t length, int flags);
} // namespace gkfs::hook

#endif
+10 −0
Changes for include/client/user_functions.hpp: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -133,6 +133,16 @@ gkfs_rename(const std::string& old_path, const std::string& new_path);
int
gkfs_fsync(unsigned int fd);

// add mmap
void*
gkfs_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset);

int
gkfs_munmap(void* addr, size_t length);

int
gkfs_msync(void* addr, size_t length, int flags);

} // namespace syscall
namespace malleable {

+60 −0
Changes for src/client/gkfs_functions.cpp: 60 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -114,6 +114,8 @@ struct dirent_extended {

namespace {

// set to store void * addr, fd, length and offset
std::set<std::tuple<void*, int, size_t, off_t>> mmap_set;
/**
 * Checks if metadata for parent directory exists (can be disabled with
 * GKFS_CREATE_CHECK_PARENTS). errno may be set
@@ -1930,6 +1932,64 @@ gkfs_get_file_list(const std::string& path) {
    return file_list;
}


void*
gkfs_mmap(void* addr, size_t length, int prot, int flags, int fd,
          off_t offset) {
    void* ptr = malloc(length);
    if(ptr == nullptr) {
        return MAP_FAILED;
    }
    // store info on mmap_set
    mmap_set.insert(std::make_tuple(ptr, fd, length, offset));
    gkfs::syscall::gkfs_pread(fd, ptr, length, offset);
    return ptr;
}

int
gkfs_msync(void* addr, size_t length, int flags) {
    // check if addr is from gekkofs (mmap_set)
    // if so, get the fd and offset
    // pwrite length to the original offset

    for(const auto& tuple : mmap_set) {
        if(std::get<0>(tuple) == addr) {
            int fd = std::get<1>(tuple);
            off_t offset = std::get<3>(tuple);
            gkfs::syscall::gkfs_pwrite(fd, addr, length, offset);
            return 0;
        }
    }
    return -1;
}


int
gkfs_munmap(void* addr, size_t length) {
    // check if addr is from gekkofs (mmap_set)
    // if so, get the fd and offset
    // pwrite length to the original offset
    // return
    // if not just go to the normal msync
    if(mmap_set.size() != 0) {
        // use find_if std::algorithm
        // if found, call msync

        auto it = std::find_if(
                mmap_set.begin(), mmap_set.end(),
                [&addr](const std::tuple<void*, int, size_t, off_t>& t) {
                    return std::get<0>(t) == addr;
                });
        if(it != mmap_set.end()) {
            gkfs_msync(addr, length, 0);
            free(addr);
            mmap_set.erase(it);
            return 0;
        }
    }
    return -1;
}

} // namespace gkfs::syscall


+38 −0
Changes for src/client/hooks.cpp: 38 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -1098,4 +1098,42 @@ hook_fadvise64(int fd, off_t offset, off_t len, int advice) {
    }
    return syscall_no_intercept_wrapper(SYS_fadvise64, fd, offset, len, advice);
}

// mmap, munmap, msync
void*
hook_mmap(void* addr, size_t length, int prot, int flags, int fd,
          off_t offset) {
    LOG(DEBUG,
        "{}() called with addr '{}' length '{}' prot '{}' flags '{}' fd '{}' offset '{}'",
        __func__, fmt::ptr(addr), length, prot, flags, fd, offset);

    if(CTX->file_map()->exist(fd)) {
        return gkfs::syscall::gkfs_mmap(addr, length, prot, flags, fd, offset);
    }
    return reinterpret_cast<void*>(syscall_no_intercept_wrapper(
            SYS_mmap, addr, length, prot, flags, fd, offset));
}

int
hook_munmap(void* addr, size_t length) {
    LOG(DEBUG, "{}() called with addr '{}' length '{}'", __func__,
        fmt::ptr(addr), length);

    auto res = gkfs::syscall::gkfs_munmap(addr, length);
    if(res == 0)
        return res;
    return syscall_no_intercept_wrapper(SYS_munmap, addr, length);
}

int
hook_msync(void* addr, size_t length, int flags) {
    LOG(DEBUG, "{}() called with addr '{}' length '{}' flags '{}'", __func__,
        fmt::ptr(addr), length, flags);

    auto res = gkfs::syscall::gkfs_msync(addr, length, flags);
    if(res == 0)
        return res;
    return syscall_no_intercept_wrapper(SYS_msync, addr, length, flags);
}

} // namespace gkfs::hook
Loading
Loading