All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH liburing 0/2] splice helpers + tests
@ 2020-02-15 22:07 Pavel Begunkov
  2020-02-15 22:07 ` [PATCH liburing 1/2] splice: add splice(2) helpers Pavel Begunkov
  2020-02-15 22:07 ` [PATCH liburing 2/2] test/splice: add basic splice tests Pavel Begunkov
  0 siblings, 2 replies; 3+ messages in thread
From: Pavel Begunkov @ 2020-02-15 22:07 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

Add splice prep helpers and some basic tests.

Pavel Begunkov (2):
  splice: add splice(2) helpers
  test/splice: add basic splice tests

 src/include/liburing.h          |  12 +++
 src/include/liburing/io_uring.h |  14 +++-
 test/Makefile                   |   4 +-
 test/splice.c                   | 138 ++++++++++++++++++++++++++++++++
 4 files changed, 165 insertions(+), 3 deletions(-)
 create mode 100644 test/splice.c

-- 
2.24.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH liburing  1/2] splice: add splice(2) helpers
  2020-02-15 22:07 [PATCH liburing 0/2] splice helpers + tests Pavel Begunkov
@ 2020-02-15 22:07 ` Pavel Begunkov
  2020-02-15 22:07 ` [PATCH liburing 2/2] test/splice: add basic splice tests Pavel Begunkov
  1 sibling, 0 replies; 3+ messages in thread
From: Pavel Begunkov @ 2020-02-15 22:07 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

Add splice helpers and update io_uring.h

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 src/include/liburing.h          | 12 ++++++++++++
 src/include/liburing/io_uring.h | 14 +++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/include/liburing.h b/src/include/liburing.h
index 8ca6cd9..16ccadd 100644
--- a/src/include/liburing.h
+++ b/src/include/liburing.h
@@ -191,6 +191,18 @@ static inline void io_uring_prep_rw(int op, struct io_uring_sqe *sqe, int fd,
 	sqe->__pad2[0] = sqe->__pad2[1] = sqe->__pad2[2] = 0;
 }
 
+static void io_uring_prep_splice(struct io_uring_sqe *sqe,
+				 int fd_in, loff_t off_in,
+				 int fd_out, loff_t off_out,
+				 unsigned int nbytes, int splice_flags)
+{
+	io_uring_prep_rw(IORING_OP_SPLICE, sqe, fd_out, (void *)off_in,
+			 nbytes, off_out);
+	sqe->splice_fd_in = fd_in;
+	sqe->splice_flags = splice_flags;
+}
+
+
 static inline void io_uring_prep_readv(struct io_uring_sqe *sqe, int fd,
 				       const struct iovec *iovecs,
 				       unsigned nr_vecs, off_t offset)
diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h
index 424fb4b..0623e00 100644
--- a/src/include/liburing/io_uring.h
+++ b/src/include/liburing/io_uring.h
@@ -23,7 +23,10 @@ struct io_uring_sqe {
 		__u64	off;	/* offset into file */
 		__u64	addr2;
 	};
-	__u64	addr;		/* pointer to buffer or iovecs */
+	union {
+		__u64	addr;	/* pointer to buffer or iovecs */
+		__u64	off_in;
+	};
 	__u32	len;		/* buffer size or number of iovecs */
 	union {
 		__kernel_rwf_t	rw_flags;
@@ -37,6 +40,7 @@ struct io_uring_sqe {
 		__u32		open_flags;
 		__u32		statx_flags;
 		__u32		fadvise_advice;
+		__u32		splice_flags;
 	};
 	__u64	user_data;	/* data to be passed back at completion time */
 	union {
@@ -45,6 +49,7 @@ struct io_uring_sqe {
 			__u16	buf_index;
 			/* personality to use, if used */
 			__u16	personality;
+			__u32	splice_fd_in;
 		};
 		__u64	__pad2[3];
 	};
@@ -113,6 +118,7 @@ enum {
 	IORING_OP_RECV,
 	IORING_OP_OPENAT2,
 	IORING_OP_EPOLL_CTL,
+	IORING_OP_SPLICE,
 
 	/* this goes last, obviously */
 	IORING_OP_LAST,
@@ -128,6 +134,12 @@ enum {
  */
 #define IORING_TIMEOUT_ABS	(1U << 0)
 
+/*
+ * sqe->splice_flags
+ * extends splice(2) flags
+ */
+#define SPLICE_F_FD_IN_FIXED	(1U << 31) /* last bit for __u32 */
+
 /*
  * IO completion data structure (Completion Queue Entry)
  */
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH liburing 2/2] test/splice: add basic splice tests
  2020-02-15 22:07 [PATCH liburing 0/2] splice helpers + tests Pavel Begunkov
  2020-02-15 22:07 ` [PATCH liburing 1/2] splice: add splice(2) helpers Pavel Begunkov
@ 2020-02-15 22:07 ` Pavel Begunkov
  1 sibling, 0 replies; 3+ messages in thread
From: Pavel Begunkov @ 2020-02-15 22:07 UTC (permalink / raw)
  To: Jens Axboe, io-uring, linux-kernel

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 test/Makefile |   4 +-
 test/splice.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 140 insertions(+), 2 deletions(-)
 create mode 100644 test/splice.c

diff --git a/test/Makefile b/test/Makefile
index cf91011..94bbd18 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -20,7 +20,7 @@ all_targets += poll poll-cancel ring-leak fsync io_uring_setup io_uring_register
 		connect 7ad0e4b2f83c-test submit-reuse fallocate open-close \
 		file-update statx accept-reuse poll-v-poll fadvise madvise \
 		short-read openat2 probe shared-wq personality eventfd \
-		send_recv eventfd-ring across-fork
+		send_recv eventfd-ring across-fork splice
 
 include ../Makefile.quiet
 
@@ -47,7 +47,7 @@ test_srcs := poll.c poll-cancel.c ring-leak.c fsync.c io_uring_setup.c \
 	7ad0e4b2f83c-test.c submit-reuse.c fallocate.c open-close.c \
 	file-update.c statx.c accept-reuse.c poll-v-poll.c fadvise.c \
 	madvise.c short-read.c openat2.c probe.c shared-wq.c \
-	personality.c eventfd.c eventfd-ring.c across-fork.c
+	personality.c eventfd.c eventfd-ring.c across-fork.c splice.c
 
 test_objs := $(patsubst %.c,%.ol,$(test_srcs))
 
diff --git a/test/splice.c b/test/splice.c
new file mode 100644
index 0000000..92b3195
--- /dev/null
+++ b/test/splice.c
@@ -0,0 +1,138 @@
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include "liburing.h"
+
+static int copy_single(struct io_uring *ring,
+			int fd_in, loff_t off_in,
+			int fd_out, loff_t off_out,
+			unsigned int len,
+			unsigned flags1, unsigned flags2)
+{
+	struct io_uring_cqe *cqe;
+	struct io_uring_sqe *sqe;
+	int ret, i, err = -1;
+	int pipe_fds[2] = {-1, -1};
+
+	if (pipe(pipe_fds) < 0)
+		goto exit;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		printf("get sqe failed\n");
+		goto exit;
+	}
+	io_uring_prep_splice(sqe, fd_in, off_in, pipe_fds[1], -1,
+			     len, flags1);
+	sqe->user_data = 1;
+	sqe->flags = IOSQE_IO_LINK;
+
+	sqe = io_uring_get_sqe(ring);
+	if (!sqe) {
+		printf("get sqe failed\n");
+		goto exit;
+	}
+	io_uring_prep_splice(sqe, pipe_fds[0], -1, fd_out, off_out,
+			     len, flags2);
+	sqe->user_data = 2;
+
+	ret = io_uring_submit(ring);
+	if (ret <= 0) {
+		printf("sqe submit failed: %d\n", ret);
+		goto exit;
+	}
+
+	for (i = 0; i < 2; i++) {
+		ret = io_uring_wait_cqe(ring, &cqe);
+		if (ret < 0 || cqe->res != len) {
+			printf("wait completion %d\n", cqe->res);
+			goto exit;
+		}
+		io_uring_cqe_seen(ring, cqe);
+	}
+	err = 0;
+exit:
+	if (pipe_fds[0] >= 0) {
+		close(pipe_fds[0]);
+		close(pipe_fds[1]);
+	}
+	return err;
+}
+
+static int test_splice(struct io_uring *ring)
+{
+	int ret, err = 1;
+	int len = 4 * 4096;
+	int fd_out = -1, fd_in = -1;
+	int fd_in_idx;
+
+	fd_in = open("/dev/urandom", O_RDONLY);
+	if (fd_in < 0)
+		goto exit;
+	fd_out = memfd_create("splice_test_out_file", 0);
+	if (fd_out < 0)
+		goto exit;
+	if (ftruncate(fd_out, len) == -1)
+		goto exit;
+
+	ret = copy_single(ring, fd_in, -1, fd_out, -1, len,
+			  SPLICE_F_MOVE | SPLICE_F_MORE, 0);
+	if (ret) {
+		printf("basic splice-copy failed\n");
+		goto exit;
+	}
+
+	ret = copy_single(ring, fd_in, 0, fd_out, 0, len,
+			  0, SPLICE_F_MOVE | SPLICE_F_MORE);
+	if (ret) {
+		printf("basic splice with offset failed\n");
+		goto exit;
+	}
+
+	fd_in_idx = 0;
+	ret = io_uring_register_files(ring, &fd_in, 1);
+	if (ret) {
+		fprintf(stderr, "%s: register ret=%d\n", __FUNCTION__, ret);
+		goto exit;
+	}
+
+	ret = copy_single(ring, fd_in_idx, 0, fd_out, 0, len,
+			  SPLICE_F_FD_IN_FIXED, 0);
+	if (ret) {
+		printf("basic splice with reg files failed\n");
+		goto exit;
+	}
+
+	err = 0;
+exit:
+	if (fd_out >= 0)
+		close(fd_out);
+	if (fd_in >= 0)
+		close(fd_in);
+	return err;
+}
+
+int main(int argc, char *argv[])
+{
+	struct io_uring ring;
+	int ret;
+
+	ret = io_uring_queue_init(8, &ring, 0);
+	if (ret) {
+		printf("ring setup failed\n");
+		return 1;
+	}
+
+	ret = test_splice(&ring);
+	if (ret) {
+		printf("test_splice failed %i %i\n", ret, errno);
+		return ret;
+	}
+
+	return 0;
+}
-- 
2.24.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-02-15 22:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-02-15 22:07 [PATCH liburing 0/2] splice helpers + tests Pavel Begunkov
2020-02-15 22:07 ` [PATCH liburing 1/2] splice: add splice(2) helpers Pavel Begunkov
2020-02-15 22:07 ` [PATCH liburing 2/2] test/splice: add basic splice tests Pavel Begunkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.