Commit 5d8da9b3 authored by Jean Bez's avatar Jean Bez Committed by Ramon Nou
Browse files

[readv and preadv] Implementation and tests. Fixes #84

parent 082832dd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -84,6 +84,9 @@ ssize_t gkfs_pread_ws(int fd, void* buf, size_t count, off64_t offset);

ssize_t gkfs_read(int fd, void* buf, size_t count);

ssize_t gkfs_readv(int fd, const struct iovec* iov, int iovcnt);

ssize_t gkfs_preadv(int fd, const struct iovec* iov, int iovcnt, off_t offset);

int gkfs_opendir(const std::string& path);

+5 −0
Original line number Diff line number Diff line
@@ -42,6 +42,11 @@ int hook_read(unsigned int fd, void* buf, size_t count);

int hook_pread(unsigned int fd, char* buf, size_t count, loff_t pos);

int hook_readv(unsigned long fd, const struct iovec * iov, unsigned long iovcnt);

int hook_preadv(unsigned long fd, const struct iovec * iov, unsigned long iovcnt,
                 unsigned long pos_l, unsigned long pos_h);

int hook_write(unsigned int fd, const char* buf, size_t count);

int hook_pwrite(unsigned int fd, const char* buf, size_t count, loff_t pos);
+43 −0
Original line number Diff line number Diff line
@@ -521,6 +521,49 @@ ssize_t gkfs_read(int fd, void* buf, size_t count) {
    return ret;
}

ssize_t gkfs_preadv(int fd, const struct iovec* iov, int iovcnt, off_t offset) {

    auto file = CTX->file_map()->get(fd);
    auto pos = offset; // keep truck of current position
    ssize_t read = 0;
    ssize_t ret;
    for (int i = 0; i < iovcnt; ++i) {
        auto count = (iov + i)->iov_len;
        if (count == 0) {
            continue;
        }
        auto buf = (iov + i)->iov_base;
        ret = gkfs_pread(file, reinterpret_cast<char*>(buf), count, pos);
        if (ret == -1) {
            break;
        }
        read += ret;
        pos += ret;

        if (static_cast<size_t>(ret) < count) {
            break;
        }
    }

    if (read == 0) {
        return -1;
    }
    return read;
}

ssize_t gkfs_readv(int fd, const struct iovec* iov, int iovcnt) {

    auto gkfs_fd = CTX->file_map()->get(fd);
    auto pos = gkfs_fd->pos(); // retrieve the current offset
    auto ret = gkfs_preadv(fd, iov, iovcnt, pos);
    assert(ret != 0);
    if (ret < 0) {
        return -1;
    }
    gkfs_fd->pos(pos + ret);
    return ret;
}

ssize_t gkfs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
    auto gkfs_fd = CTX->file_map()->get(fd);
    return gkfs_pread(gkfs_fd, reinterpret_cast<char*>(buf), count, offset);
+26 −2
Original line number Diff line number Diff line
@@ -209,6 +209,30 @@ int hook_pread(unsigned int fd, char* buf, size_t count, loff_t pos) {
    return syscall_no_intercept(SYS_pread64, fd, buf, count, pos);
}

int hook_readv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt) {

    LOG(DEBUG, "{}() called with fd: {}, iov: {}, iovcnt: {}",
        __func__, fd, fmt::ptr(iov), iovcnt);

    if (CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_readv(fd, iov, iovcnt));
    }
    return syscall_no_intercept(SYS_readv, fd, iov, iovcnt);
}

int hook_preadv(unsigned long fd, const struct iovec* iov, unsigned long iovcnt,
                 unsigned long pos_l, unsigned long pos_h) {

    LOG(DEBUG, "{}() called with fd: {}, iov: {}, iovcnt: {}, "
               "pos_l: {}," "pos_h: {}",
        __func__, fd, fmt::ptr(iov), iovcnt, pos_l, pos_h);

    if (CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_preadv(fd, iov, iovcnt, pos_l));
    }
    return syscall_no_intercept(SYS_preadv, fd, iov, iovcnt, pos_l);
}

int hook_write(unsigned int fd, const char* buf, size_t count) {

    LOG(DEBUG, "{}() called with fd: {}, buf: {}, count {}",
@@ -253,7 +277,7 @@ int hook_pwritev(unsigned long fd, const struct iovec* iov, unsigned long iovcnt
    if (CTX->file_map()->exist(fd)) {
        return with_errno(gkfs::syscall::gkfs_pwritev(fd, iov, iovcnt, pos_l));
    }
    return syscall_no_intercept(SYS_pwritev, fd, iov, iovcnt);
    return syscall_no_intercept(SYS_pwritev, fd, iov, iovcnt, pos_l);
}

int hook_unlinkat(int dirfd, const char* cpath, int flags) {
+14 −0
Original line number Diff line number Diff line
@@ -506,6 +506,20 @@ int hook(long syscall_number,
                                             static_cast<loff_t>(arg3));
            break;

        case SYS_readv:
            *result = gkfs::hook::hook_readv(static_cast<unsigned long>(arg0),
                                              reinterpret_cast<const struct iovec*>(arg1),
                                              static_cast<unsigned long>(arg2));
            break;

        case SYS_preadv:
            *result = gkfs::hook::hook_preadv(static_cast<unsigned long>(arg0),
                                               reinterpret_cast<const struct iovec*>(arg1),
                                               static_cast<unsigned long>(arg2),
                                               static_cast<unsigned long>(arg3),
                                               static_cast<unsigned long>(arg4));
            break;

        case SYS_pwrite64:
            *result = gkfs::hook::hook_pwrite(static_cast<unsigned int>(arg0),
                                              reinterpret_cast<const char*>(arg1),
Loading