Verified Commit 46fe25b9 authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

Refactor adafs internal read/write funciton

 - Added adafs_pwrite and adafs_pread functions:
        they accept an OpenFile pointer instead of a fd so that can be
        called by function that already accessed the OpenFileMap.

 - Moved the writev function into internal adafs functions.

 - Added internal adafs_write function:
        instead messing up with the file position at the interception
        layer, we can use this internal function that hides the update of the
        file position two.
parent 5989e600
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -54,11 +54,18 @@ int adafs_dup(int oldfd);

int adafs_dup2(int oldfd, int newfd);


ssize_t adafs_pwrite(std::shared_ptr<OpenFile> file,
                     const char * buf, size_t count, off64_t offset);
ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset);
ssize_t adafs_write(int fd, const void * buf, size_t count);
ssize_t adafs_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
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_pread_ws(int fd, void* buf, size_t count, off64_t offset);

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

+98 −24
Original line number Diff line number Diff line
@@ -303,26 +303,24 @@ int adafs_dup2(const int oldfd, const int newfd) {
    return CTX->file_map()->dup2(oldfd, newfd);
}


ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset) {
ssize_t adafs_pwrite(std::shared_ptr<OpenFile> file, const char * buf, size_t count, off64_t offset) {
    init_ld_env_if_needed();
    auto adafs_fd = CTX->file_map()->get(fd);
    if (adafs_fd->type() != FileType::regular) {
        assert(adafs_fd->type() == FileType::directory);
    if (file->type() != FileType::regular) {
        assert(file->type() == FileType::directory);
        CTX->log()->warn("{}() cannot read from directory", __func__);
        errno = EISDIR;
        return -1;
    }
    auto path = make_shared<string>(adafs_fd->path());
    CTX->log()->trace("{}() fd: {}, count: {}, offset: {}", __func__, fd, count, offset);
    auto append_flag = adafs_fd->get_flag(OpenFile_flags::append);
    auto path = make_shared<string>(file->path());
    CTX->log()->trace("{}() count: {}, offset: {}", __func__, count, offset);
    auto append_flag = file->get_flag(OpenFile_flags::append);
    ssize_t ret = 0;
    long updated_size = 0;

    ret = rpc_send_update_metadentry_size(*path, count, offset, append_flag, updated_size);
    if (ret != 0) {
        CTX->log()->error("{}() update_metadentry_size failed with ret {}", __func__, ret);
        return 0; // ERR
        return ret; // ERR
    }
    ret = rpc_send_write(*path, buf, append_flag, offset, count, updated_size);
    if (ret < 0) {
@@ -331,33 +329,91 @@ ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset) {
    return ret; // return written size or -1 as error
}

ssize_t adafs_read(int fd, void* buf, size_t count) {
ssize_t adafs_pwrite_ws(int fd, const void* buf, size_t count, off64_t offset) {
    init_ld_env_if_needed();
    auto file = CTX->file_map()->get(fd);
    return adafs_pwrite(file, reinterpret_cast<const char*>(buf), count, offset);
}

/* Write counts bytes starting from current file position
 * It also update the file position accordingly
 *
 * Same as write syscall.
*/
ssize_t adafs_write(int fd, const void * buf, size_t count) {
    auto adafs_fd = CTX->file_map()->get(fd);
    auto pos = adafs_fd->pos(); //retrieve the current offset
            auto ret = adafs_pread_ws(fd, buf, count, pos);
    if (adafs_fd->get_flag(OpenFile_flags::append))
        adafs_lseek(adafs_fd, 0, SEEK_END);
    auto ret = adafs_pwrite(adafs_fd, reinterpret_cast<const char*>(buf), count, pos);
    // Update offset in file descriptor in the file map
    if (ret > 0) {
                adafs_fd->pos(pos + ret);
        adafs_fd->pos(pos + count);
    }
    return ret;
}

ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
ssize_t adafs_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
    init_ld_env_if_needed();
    CTX->log()->trace("{}() called with fd {}, op num {}, offset {}",
                      __func__, fd, iovcnt, offset);

    auto file = CTX->file_map()->get(fd);
    auto pos = offset; // keep truck of current position
    ssize_t written = 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_pwrite(file, reinterpret_cast<char *>(buf), count, pos);
        if (ret == -1) {
            break;
        }
        written += ret;
        pos += ret;

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

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

ssize_t adafs_writev(int fd, const struct iovec * iov, int iovcnt) {
    CTX->log()->trace("{}() called with fd {}, ops num {}",
            __func__, fd, iovcnt);
    auto adafs_fd = CTX->file_map()->get(fd);
    if (adafs_fd->type() != FileType::regular) {
        assert(adafs_fd->type() == FileType::directory);
    auto pos = adafs_fd->pos(); // retrieve the current offset
    auto ret = adafs_pwritev(fd, iov, iovcnt, pos);
    assert(ret != 0);
    if (ret < 0) {
        return -1;
    }
    adafs_fd->pos(pos + ret);
    return ret;
}

ssize_t adafs_pread(std::shared_ptr<OpenFile> file, char * buf, size_t count, off64_t offset) {
    init_ld_env_if_needed();
    if (file->type() != FileType::regular) {
        assert(file->type() == FileType::directory);
        CTX->log()->warn("{}() cannot read from directory", __func__);
        errno = EISDIR;
        return -1;
    }
    auto path = make_shared<string>(adafs_fd->path());
    CTX->log()->trace("{}() fd: {}, count: {}, offset: {}", __func__, fd, count, offset);
    CTX->log()->trace("{}() count: {}, offset: {}", __func__, count, offset);
    // Zeroing buffer before read is only relevant for sparse files. Otherwise sparse regions contain invalid data.
#if defined(ZERO_BUFFER_BEFORE_READ)
    memset(buf, 0, sizeof(char)*count);
#endif
    auto ret = rpc_send_read(*path, buf, offset, count);
    auto ret = rpc_send_read(file->path(), buf, offset, count);
    if (ret < 0) {
        CTX->log()->warn("{}() rpc_send_read failed with ret {}", __func__, ret);
    }
@@ -365,6 +421,24 @@ ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
    return ret; // return read size or -1 as error
}

ssize_t adafs_read(int fd, void* buf, size_t count) {
    init_ld_env_if_needed();
    auto adafs_fd = CTX->file_map()->get(fd);
    auto pos = adafs_fd->pos(); //retrieve the current offset
    auto ret = adafs_pread(adafs_fd, reinterpret_cast<char*>(buf), count, pos);
    // Update offset in file descriptor in the file map
    if (ret > 0) {
        adafs_fd->pos(pos + ret);
    }
    return ret;
}

ssize_t adafs_pread_ws(int fd, void* buf, size_t count, off64_t offset) {
    init_ld_env_if_needed();
    auto adafs_fd = CTX->file_map()->get(fd);
    return adafs_pread(adafs_fd, reinterpret_cast<char*>(buf), count, offset);
}

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

+3 −41
Original line number Diff line number Diff line
@@ -213,12 +213,9 @@ size_t intcp_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
        auto fd = file_to_fd(stream);
        if (CTX->file_map()->exist(fd)) {
            CTX->log()->trace("{}() called with fd {}", __func__, fd);
            auto adafs_fd = CTX->file_map()->get(fd);
            auto pos = adafs_fd->pos(); //retrieve the current offset
            auto ret = adafs_pwrite_ws(fd, ptr, size*nmemb, pos);
            auto ret = adafs_write(fd, ptr, size*nmemb);
            if (ret > 0) {
                // Update offset in file descriptor in the file map
                adafs_fd->pos(pos + ret);
                return ret / size;
            }
            return ret;
@@ -922,16 +919,7 @@ ssize_t write(int fd, const void* buf, size_t count) {
    if(CTX->initialized()) {
        CTX->log()->trace("{}() called with fd {}", __func__, fd);
        if (CTX->file_map()->exist(fd)) {
            auto adafs_fd = CTX->file_map()->get(fd);
            auto pos = adafs_fd->pos(); // retrieve the current offset
            if (adafs_fd->get_flag(OpenFile_flags::append))
                adafs_lseek(adafs_fd, 0, SEEK_END);
            auto ret = adafs_pwrite_ws(fd, buf, count, pos);
            // Update offset in file descriptor in the file map
            if (ret > 0) {
                adafs_fd->pos(pos + count);
            }
            return ret;
            return adafs_write(fd, buf, count);
        }
    }
    return (reinterpret_cast<decltype(&write)>(libc_write))(fd, buf, count);
@@ -964,33 +952,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovcnt) {
    if(CTX->initialized()) {
        CTX->log()->trace("{}() called with fd {}", __func__, fd);
        if (CTX->file_map()->exist(fd)) {
            auto adafs_fd = CTX->file_map()->get(fd);
            auto pos = adafs_fd->pos(); // retrieve the current offset
            ssize_t written = 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_pwrite_ws(fd, buf, count, pos);
                if(ret == -1) {
                    break;
                }
                written += ret;
                pos += ret;

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

            if(written == 0){
                return -1;
            }
            adafs_fd->pos(pos);
            return written;
            return adafs_writev(fd, iov, iovcnt);
        }
    }
    return (reinterpret_cast<decltype(&writev)>(libc_writev))(fd, iov, iovcnt);