Commit 87421281 authored by Ramon Nou's avatar Ramon Nou
Browse files

Merge branch 'rnou/199-mmap-support' into 'master'

Resolve "mmap support"

Closes #199

Partial implementation

Closes #199

See merge request !247
parents 41d9dbe8 3a6ed443
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
    - Use LIBGKFS_PROTECT_FD=1 to enable the original method of assignation and protection.
  - Lock system (server level) ([!245](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/245))
    - Use PROTECT_FILES_GENERATOR=1 and PROTECT_FILES_CONSUMER=1 to enable. Generator, creates transparent .lockgekko files that blocks the open (for some seconds) of any consumer. Multiple opens / closes for generator are managed.
  - Basic mmap support ([!247](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/245))
    
### Changed 
  - Tests check ret for -1 instead of 10000 fd ([!320](https://storage.bsc.es/gitlab/hpc/gekkofs/-/merge_requests/320))
+10 −0
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
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
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
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


Loading