Index: benchmark/io/sendfile/producer.c
===================================================================
--- benchmark/io/sendfile/producer.c	(revision 3263e2a49d27f9e862a60b38065ba8538ddd3aae)
+++ benchmark/io/sendfile/producer.c	(revision f0567a837a4f142b940e35e5251b8a7e2f6e6fe1)
@@ -47,4 +47,6 @@
 int pipefd[2];
 struct io_uring ring;
+
+char * buf;
 
 struct stats {
@@ -62,4 +64,5 @@
 static void my_iouring (int out, int in, size_t size, struct stats *);
 static void my_ringlink(int out, int in, size_t size, struct stats *);
+static void my_readwrit(int out, int in, size_t size, struct stats *);
 typedef void (*sender_t)(int out, int in, size_t size, struct stats *);
 
@@ -71,4 +74,5 @@
 	struct addrinfo * addr;
 	int file_fd;
+	int ret;
 	switch(argc) {
 	case 3:
@@ -76,5 +80,5 @@
 			// Open the file
 			const char * const path = argv[2];
-			int ret = open(path, 0, O_RDONLY);
+			ret = open(path, 0, O_RDONLY);
 			if(ret < 0) {
 				fprintf( stderr, "cannot open file '%s': %s\n\n", path, strerror(errno) );
@@ -176,33 +180,4 @@
 	io_uring_queue_init(16, &ring, 0);
 
-	{
-		char addr_str[INET_ADDRSTRLEN];
-		struct sockaddr_in * address = (struct sockaddr_in *) addr->ai_addr;
-		inet_ntop( AF_INET, &address->sin_addr, addr_str, INET_ADDRSTRLEN );
-		printf("sending '%s' to '%s:%i'\n", file_path, addr_str, ntohs(address->sin_port));
-	}
-
-	int ret = pipe(pipefd);
-	if( ret < 0 ) {
-		fprintf( stderr, "pipe error: (%d) %s\n\n", (int)errno, strerror(errno) );
-		exit( PIPE_ERROR );
-	}
-
-	{
-		ret = fcntl(pipefd[0], F_GETPIPE_SZ);
-		if( ret < 0 ) {
-			fprintf( stderr, "pipe fcntl error: (%d) %s\n\n", (int)errno, strerror(errno) );
-			exit( PIPE_ERROR );
-		}
-		printf("%d\n", ret);
-
-		ret = fcntl(pipefd[1], F_GETPIPE_SZ);
-		if( ret < 0 ) {
-			fprintf( stderr, "pipe fcntl 2 error: (%d) %s\n\n", (int)errno, strerror(errno) );
-			exit( PIPE_ERROR );
-		}
-		printf("%d\n", ret);
-	}
-
 	size_t file_size = 0;
 	{
@@ -216,4 +191,21 @@
 	}
 
+	{
+		char addr_str[INET_ADDRSTRLEN];
+		struct sockaddr_in * address = (struct sockaddr_in *) addr->ai_addr;
+		inet_ntop( AF_INET, &address->sin_addr, addr_str, INET_ADDRSTRLEN );
+		printf("sending '%s' (%zu bytes) to '%s:%i'\n", file_path, file_size, addr_str, ntohs(address->sin_port));
+	}
+
+	ret = pipe(pipefd);
+	if( ret < 0 ) {
+		fprintf( stderr, "pipe error: (%d) %s\n\n", (int)errno, strerror(errno) );
+		exit( PIPE_ERROR );
+	}
+
+	buf = malloc(file_size);
+
+	printf("--- read + write ---\n");
+	run(my_readwrit, addr, file_fd, file_size);
 	printf("--- splice ---\n");
 	run(my_splice  , addr, file_fd, file_size);
@@ -414,4 +406,5 @@
 			io_uring_prep_splice(sqe, in, offset, pipefd[1], -1, size, 0);
 			sqe->user_data = SPLICE_IN;
+			sqe->flags = IOSQE_IO_LINK;
 			has_in = true;
 		}
@@ -420,5 +413,4 @@
 			io_uring_prep_splice(sqe, pipefd[0], -1, out, -1, in_pipe, 0);
 			sqe->user_data = SPLICE_OUT;
-			if(has_in) sqe->flags = IOSQE_IO_LINK;
 			has_out = true;
 		}
@@ -481,2 +473,37 @@
 	st->calls++;
 }
+
+static void my_readwrit(int out, int in, size_t size, struct stats * st) {
+	off_t offset = 0;
+	size_t writes = 0;
+	for(;;) {
+		ssize_t reti = pread(in, buf, size, offset);
+		if( reti < 0 ) {
+			printf("Read in Error : (%d) %s\n\n", (int)errno, strerror(errno) );
+			exit( 1 );
+		}
+
+		offset += reti;
+		size -= reti;
+
+		size_t in_buf = reti;
+		for(;;) {
+			ssize_t reto = write(out, buf, in_buf);
+			if( reto < 0 ) {
+					printf("Write out Error : (%d) %s\n\n", (int)errno, strerror(errno) );
+					exit( 1 );
+				}
+
+			in_buf -= reto;
+			writes += reto;
+			if(0 == in_buf) break;
+			st->shorts.w.cnt++;
+			st->shorts.w.bytes += reto;
+		}
+		if(0 == size) break;
+		st->shorts.r.cnt++;
+		st->shorts.r.bytes += reti;
+	}
+	st->calls++;
+	st->bytes += writes;
+}
