Commit 667d39a8 authored by Jean Bez's avatar Jean Bez
Browse files

implement readv and preadv, fix writev and pwritev

parent 725a53b6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -65,7 +65,8 @@ ssize_t adafs_writev(int fd, const struct iovec * iov, int iovcnt);
ssize_t adafs_pread(std::shared_ptr<OpenFile> file, char * buf, size_t count, off64_t offset);
ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset);
ssize_t adafs_read(int fd, void* buf, size_t count);

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

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

+3 −0
Original line number Diff line number Diff line
@@ -26,6 +26,9 @@ int hook_fstat(unsigned int fd, struct stat* buf);
int hook_fstatat(int dirfd, const char * cpath, struct stat * buf, int flags);
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);
int hook_writev(unsigned long fd, const struct iovec * iov, unsigned long iovcnt);
+44 −0
Original line number Diff line number Diff line
@@ -492,6 +492,50 @@ ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
    return adafs_pread(adafs_fd, reinterpret_cast<char*>(buf), count, offset);
}

ssize_t adafs_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 = adafs_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 adafs_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 = adafs_preadv(fd, iov, iovcnt, pos);
    assert(ret != 0);
    if (ret < 0) {
        return -1;
    }
    gkfs_fd->pos(pos + ret);
    return ret;
}


int adafs_opendir(const std::string& path) {

    auto md = adafs_metadata(path);
+26 −3
Original line number Diff line number Diff line
@@ -165,6 +165,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(adafs_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(adafs_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 {}", 
@@ -207,10 +231,9 @@ int hook_pwritev(unsigned long fd, const struct iovec * iov, unsigned long iovcn
        __func__, fd, fmt::ptr(iov), iovcnt, pos_l, pos_h);

    if (CTX->file_map()->exist(fd)) {
        LOG(WARNING, "{}() Not supported", __func__);
        return -ENOTSUP;
        return with_errno(adafs_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
@@ -498,6 +498,20 @@ int hook(long syscall_number,
                                static_cast<loff_t>(arg3));
            break;

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

        case SYS_preadv:
            *result = 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 = hook_pwrite(static_cast<unsigned int>(arg0),
                                reinterpret_cast<const char *>(arg1),