diff --git a/src/nbd_proxy.cpp b/src/nbd_proxy.cpp index 956185a6..5157f196 100644 --- a/src/nbd_proxy.cpp +++ b/src/nbd_proxy.cpp @@ -26,6 +26,18 @@ const char *exe_name = NULL; +static inline void my_uring_prep_splice(struct io_uring_sqe *sqe, + int fd_in, int64_t off_in, + int fd_out, int64_t off_out, + unsigned int nbytes, + unsigned int splice_flags) +{ + my_uring_prep_rw(IORING_OP_SPLICE, sqe, fd_out, NULL, nbytes, (__u64) off_out); + sqe->splice_off_in = (__u64) off_in; + sqe->splice_fd_in = fd_in; + sqe->splice_flags = splice_flags; +} + struct buf_to_free_t { void *buf = NULL; @@ -61,6 +73,7 @@ protected: mmap_manager_t mm; int pipe_fd[2]; + int vmspliced = 0; public: static json11::Json::object parse_args(int narg, const char *args[]) @@ -571,12 +584,29 @@ protected: } else { - int res = vmsplice(pipe_fd[1], send_list.data(), 1, SPLICE_F_GIFT); - if (res < 0) + io_uring_sqe* sqe = ringloop->get_sqe(); + if (!sqe) { - throw std::runtime_error(std::string("vmsplice: ")+strerror(errno)); + return; } - int sent = res, spl = res; + if (vmspliced <= 0) + { + vmspliced = vmsplice(pipe_fd[1], send_list.data(), 1, SPLICE_F_GIFT); + if (vmspliced < 0) + { + throw std::runtime_error(std::string("vmsplice: ")+strerror(errno)); + } + } + send_msg.msg_iovlen = 1; + ring_data_t* data = ((ring_data_t*)sqe->user_data); + data->callback = [this](ring_data_t *data) + { + if (data->res > 0) + vmspliced -= data->res; + handle_send(data->res); + }; + my_uring_prep_splice(sqe, pipe_fd[0], -1l, nbd_fd, -1l, vmspliced, SPLICE_F_MOVE); + /*int sent = res, spl = res; while (spl > 0) { res = splice(pipe_fd[0], NULL, nbd_fd, NULL, spl, SPLICE_F_MOVE); @@ -590,7 +620,7 @@ protected: spl -= res; } } - handle_send(sent); + handle_send(sent);*/ } }