Add support for queuing > 1 command at the time

For the async engines, we currently do queuing by issuing one
command at the the time. Improve this by adding a ->commit()
hook to complement the ->queue() hook. When ->queue() returns
FIO_Q_BUSY, call ->commit() to actually send off the io to the
kernel.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/fio.c b/fio.c
index 6e78949..858d6b8 100644
--- a/fio.c
+++ b/fio.c
@@ -209,6 +209,7 @@
 		return 1;
 	}
 
+requeue:
 	ret = td_io_queue(td, io_u);
 	if (ret < 0) {
 		td_verror(td, io_u->error);
@@ -224,6 +225,10 @@
 		}
 
 		io_u_sync_complete(td, io_u, NULL);
+	} else if (ret == FIO_Q_BUSY) {
+		if (td_io_commit(td))
+			return 1;
+		goto requeue;
 	}
 
 	return 0;
@@ -285,6 +290,10 @@
 			continue;
 		case FIO_Q_QUEUED:
 			break;
+		case FIO_Q_BUSY:
+			requeue_io_u(td, &io_u);
+			ret = td_io_commit(td);
+			break;
 		default:
 			assert(ret < 0);
 			td_verror(td, -ret);
@@ -299,7 +308,7 @@
 		 * completed io_u's first.
 		 */
 		min_events = 0;
-		if (queue_full(td))
+		if (queue_full(td) || ret == FIO_Q_BUSY)
 			min_events = 1;
 
 		/*
@@ -403,6 +412,10 @@
 			break;
 		case FIO_Q_QUEUED:
 			break;
+		case FIO_Q_BUSY:
+			requeue_io_u(td, &io_u);
+			ret = td_io_commit(td);
+			break;
 		default:
 			assert(ret < 0);
 			put_io_u(td, io_u);
@@ -412,14 +425,15 @@
 		if (ret < 0 || td->error)
 			break;
 
-		add_slat_sample(td, io_u->ddir, mtime_since(&io_u->start_time, &io_u->issue_time));
+		if (io_u)
+			add_slat_sample(td, io_u->ddir, mtime_since(&io_u->start_time, &io_u->issue_time));
 
 		/*
 		 * See if we need to complete some commands
 		 */
-		if (ret == FIO_Q_QUEUED) {
+		if (ret == FIO_Q_QUEUED || ret == FIO_Q_BUSY) {
 			min_evts = 0;
-			if (queue_full(td))
+			if (queue_full(td) || ret == FIO_Q_BUSY)
 				min_evts = 1;
 
 			fio_gettime(&comp_time, NULL);
@@ -633,6 +647,7 @@
 
 	INIT_LIST_HEAD(&td->io_u_freelist);
 	INIT_LIST_HEAD(&td->io_u_busylist);
+	INIT_LIST_HEAD(&td->io_u_requeues);
 	INIT_LIST_HEAD(&td->io_hist_list);
 	INIT_LIST_HEAD(&td->io_log_list);