Don't allow pre_read on IO engines that cannot seek

We cannot pre-read files, if we cannot seek back and read the same
data again. So just disable it with a warning to the user.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/HOWTO b/HOWTO
index 3107d3a..708eca0 100644
--- a/HOWTO
+++ b/HOWTO
@@ -741,7 +741,10 @@
 pre_read=bool	If this is given, files will be pre-read into memory before
 		starting the given IO operation. This will also clear
 		the 'invalidate' flag, since it is pointless to pre-read
-		and then drop the cache.
+		and then drop the cache. This will only work for IO engines
+		that are seekable, since they allow you to read the same data
+		multiple times. Thus it will not work on eg network or splice
+		IO.
 
 unlink=bool	Unlink the job files when done. Not the default, as repeated
 		runs of that job would then waste time recreating the file
diff --git a/engines/net.c b/engines/net.c
index 4ddacf2..c0a793e 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -633,7 +633,7 @@
 	.open_file	= fio_netio_open_file,
 	.close_file	= generic_close_file,
 	.flags		= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
-			  FIO_SIGQUIT,
+			  FIO_SIGQUIT | FIO_PIPEIO,
 };
 #endif
 
@@ -648,7 +648,7 @@
 	.open_file	= fio_netio_open_file,
 	.close_file	= fio_netio_close_file,
 	.flags		= FIO_SYNCIO | FIO_DISKLESSIO | FIO_UNIDIR |
-			  FIO_SIGQUIT,
+			  FIO_SIGQUIT | FIO_PIPEIO,
 };
 
 static void fio_init fio_netio_register(void)
diff --git a/engines/splice.c b/engines/splice.c
index 28e1fb0..ca43e43 100644
--- a/engines/splice.c
+++ b/engines/splice.c
@@ -297,7 +297,7 @@
 	.open_file	= generic_open_file,
 	.close_file	= generic_close_file,
 	.get_file_size	= generic_get_file_size,
-	.flags		= FIO_SYNCIO,
+	.flags		= FIO_SYNCIO | FIO_PIPEIO,
 };
 
 #else /* FIO_HAVE_SPLICE */
diff --git a/filesetup.c b/filesetup.c
index a0a4b80..1a5a7ec 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -156,6 +156,9 @@
 	unsigned int bs;
 	char *b;
 
+	if (td->io_ops->flags & FIO_PIPEIO)
+		return 0;
+
 	if (!fio_file_open(f)) {
 		if (td->io_ops->open_file(td, f)) {
 			log_err("fio: cannot pre-read, failed to open file\n");
diff --git a/fio.1 b/fio.1
index aa7b9d6..32993b6 100644
--- a/fio.1
+++ b/fio.1
@@ -544,7 +544,9 @@
 .BI pre_read \fR=\fPbool
 If this is given, files will be pre-read into memory before starting the given
 IO operation. This will also clear the \fR \fBinvalidate\fR flag, since it is
-pointless to pre-read and then drop the cache.
+pointless to pre-read and then drop the cache. This will only work for IO
+engines that are seekable, since they allow you to read the same data
+multiple times. Thus it will not work on eg network or splice IO.
 .TP
 .BI unlink \fR=\fPbool
 Unlink job files when done.  Default: false.
diff --git a/init.c b/init.c
index 305f660..160bdff 100644
--- a/init.c
+++ b/init.c
@@ -350,8 +350,12 @@
 	if (td->o.verify != VERIFY_NONE)
 		td->o.refill_buffers = 1;
 
-	if (td->o.pre_read)
+	if (td->o.pre_read) {
 		td->o.invalidate_cache = 0;
+		if (td->io_ops->flags & FIO_PIPEIO)
+			log_info("fio: cannot pre-read files with an IO engine"
+				 " that isn't seekable. Pre-read disabled.\n");
+	}
 
 	if (td->o.mem_align) {
 		if (td->o.odirect && !is_power_of_2(td->o.mem_align)) {
diff --git a/ioengine.h b/ioengine.h
index 6190977..f977799 100644
--- a/ioengine.h
+++ b/ioengine.h
@@ -112,6 +112,7 @@
 	FIO_UNIDIR	= 1 << 5,	/* engine is uni-directional */
 	FIO_NOIO	= 1 << 6,	/* thread does only pseudo IO */
 	FIO_SIGQUIT	= 1 << 7,	/* needs SIGQUIT to exit */
+	FIO_PIPEIO	= 1 << 8,	/* input/output no seekable */
 };
 
 /*