Add number_ios= option

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/HOWTO b/HOWTO
index 2335a07..005dac2 100644
--- a/HOWTO
+++ b/HOWTO
@@ -709,6 +709,13 @@
 		which are intended to operate on a file in parallel in disjoint
 		segments, with even spacing between the starting points.
 
+number_ios=int	Fio will normally perform IOs until it has exhausted the size
+		of the region set by size=, or if it exhaust the allocated
+		time (or hits an error condition). With this setting, the
+		range/size can be set independently of the number of IOs to
+		perform. When fio reaches this number, it will exit normally
+		and report status.
+
 fsync=int	If writing to a file, issue a sync of the dirty data
 		for every number of blocks given. For example, if you give
 		32 as a parameter, fio will sync the file for every 32
diff --git a/cconv.c b/cconv.c
index 8e7c69e..21e3a51 100644
--- a/cconv.c
+++ b/cconv.c
@@ -146,6 +146,7 @@
 	o->zone_skip = le64_to_cpu(top->zone_skip);
 	o->lockmem = le64_to_cpu(top->lockmem);
 	o->offset_increment = le64_to_cpu(top->offset_increment);
+	o->number_ios = le64_to_cpu(top->number_ios);
 
 	o->overwrite = le32_to_cpu(top->overwrite);
 	o->bw_avg_time = le32_to_cpu(top->bw_avg_time);
@@ -394,6 +395,7 @@
 	top->start_offset = __cpu_to_le64(o->start_offset);
 	top->trim_backlog = __cpu_to_le64(o->trim_backlog);
 	top->offset_increment = __cpu_to_le64(o->offset_increment);
+	top->number_ios = __cpu_to_le64(o->number_ios);
 
 	for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++)
 		top->percentile_list[i].u.i = __cpu_to_le64(fio_double_to_uint64(o->percentile_list[i].u.f));
diff --git a/fio.1 b/fio.1
index b54eead..e35bd93 100644
--- a/fio.1
+++ b/fio.1
@@ -576,6 +576,13 @@
 there are several jobs which are intended to operate on a file in parallel in
 disjoint segments, with even spacing between the starting points.
 .TP
+.BI number_ios \fR=\fPint
+Fio will normally perform IOs until it has exhausted the size of the region
+set by \fBsize\fR, or if it exhaust the allocated time (or hits an error
+condition). With this setting, the range/size can be set independently of
+the number of IOs to perform. When fio reaches this number, it will exit
+normally and report status.
+.TP
 .BI fsync \fR=\fPint
 How many I/Os to perform before issuing an \fBfsync\fR\|(2) of dirty data.  If
 0, don't sync.  Default: 0.
diff --git a/io_u.c b/io_u.c
index a35aafd..c50a17d 100644
--- a/io_u.c
+++ b/io_u.c
@@ -1413,6 +1413,9 @@
 		add_bw_sample(td, idx, bytes, &icd->time);
 
 	add_iops_sample(td, idx, bytes, &icd->time);
+
+	if (td->o.number_ios && !--td->o.number_ios)
+		td->done = 1;
 }
 
 static long long usec_for_io(struct thread_data *td, enum fio_ddir ddir)
diff --git a/options.c b/options.c
index 1816d0b..caf89d3 100644
--- a/options.c
+++ b/options.c
@@ -1483,6 +1483,16 @@
 		.group	= FIO_OPT_G_INVALID,
 	},
 	{
+		.name	= "number_ios",
+		.lname	= "Number of IOs to perform",
+		.type	= FIO_OPT_STR_VAL,
+		.off1	= td_var_offset(number_ios),
+		.help	= "Force job completion of this number of IOs",
+		.def	= "0",
+		.category = FIO_OPT_C_IO,
+		.group	= FIO_OPT_G_INVALID,
+	},
+	{
 		.name	= "bs",
 		.lname	= "Block size",
 		.alias	= "blocksize",
diff --git a/server.h b/server.h
index 2f41be0..aefd418 100644
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@
 };
 
 enum {
-	FIO_SERVER_VER			= 24,
+	FIO_SERVER_VER			= 25,
 
 	FIO_SERVER_MAX_FRAGMENT_PDU	= 1024,
 
diff --git a/thread_options.h b/thread_options.h
index eaafaee..3f345c5 100644
--- a/thread_options.h
+++ b/thread_options.h
@@ -236,6 +236,7 @@
 	unsigned int flow_sleep;
 
 	unsigned long long offset_increment;
+	unsigned long long number_ios;
 
 	unsigned int sync_file_range;
 };
@@ -440,6 +441,7 @@
 	uint32_t flow_sleep;
 
 	uint64_t offset_increment;
+	uint64_t number_ios;
 
 	uint32_t sync_file_range;
 } __attribute__((packed));