[PATCH] First cut at supporting > 1 file per job

This is likely very buggy, a simple test works though.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/engines/fio-engine-cpu.c b/engines/fio-engine-cpu.c
index 9a32330..538fc86 100644
--- a/engines/fio-engine-cpu.c
+++ b/engines/fio-engine-cpu.c
@@ -15,7 +15,7 @@
 		td->cpuload = 100;
 
 	td->read_iolog = td->write_iolog = 0;
-	td->fd = -1;
+	td->nr_files = 0;
 
 	return 0;
 }
diff --git a/engines/fio-engine-libaio.c b/engines/fio-engine-libaio.c
index 703808b..9197107 100644
--- a/engines/fio-engine-libaio.c
+++ b/engines/fio-engine-libaio.c
@@ -17,17 +17,19 @@
 	struct io_event *aio_events;
 };
 
-static int fio_libaio_sync(struct thread_data *td)
+static int fio_libaio_sync(struct thread_data *td, struct fio_file *f)
 {
-	return fsync(td->fd);
+	return fsync(f->fd);
 }
 
 static int fio_libaio_prep(struct thread_data *td, struct io_u *io_u)
 {
+	struct fio_file *f = io_u->file;
+
 	if (io_u->ddir == DDIR_READ)
-		io_prep_pread(&io_u->iocb, td->fd, io_u->buf, io_u->buflen, io_u->offset);
+		io_prep_pread(&io_u->iocb, f->fd, io_u->buf, io_u->buflen, io_u->offset);
 	else
-		io_prep_pwrite(&io_u->iocb, td->fd, io_u->buf, io_u->buflen, io_u->offset);
+		io_prep_pwrite(&io_u->iocb, f->fd, io_u->buf, io_u->buflen, io_u->offset);
 
 	return 0;
 }
diff --git a/engines/fio-engine-mmap.c b/engines/fio-engine-mmap.c
index abb42bf..ad294f5 100644
--- a/engines/fio-engine-mmap.c
+++ b/engines/fio-engine-mmap.c
@@ -42,21 +42,22 @@
 
 static int fio_mmapio_queue(struct thread_data *td, struct io_u *io_u)
 {
-	unsigned long long real_off = io_u->offset - td->file_offset;
+	struct fio_file *f = io_u->file;
+	unsigned long long real_off = io_u->offset - f->file_offset;
 	struct mmapio_data *sd = td->io_ops->data;
 
 	if (io_u->ddir == DDIR_READ)
-		memcpy(io_u->buf, td->mmap + real_off, io_u->buflen);
+		memcpy(io_u->buf, f->mmap + real_off, io_u->buflen);
 	else
-		memcpy(td->mmap + real_off, io_u->buf, io_u->buflen);
+		memcpy(f->mmap + real_off, io_u->buf, io_u->buflen);
 
 	/*
 	 * not really direct, but should drop the pages from the cache
 	 */
 	if (td->odirect) {
-		if (msync(td->mmap + real_off, io_u->buflen, MS_SYNC) < 0)
+		if (msync(f->mmap + real_off, io_u->buflen, MS_SYNC) < 0)
 			io_u->error = errno;
-		if (madvise(td->mmap + real_off, io_u->buflen,  MADV_DONTNEED) < 0)
+		if (madvise(f->mmap + real_off, io_u->buflen,  MADV_DONTNEED) < 0)
 			io_u->error = errno;
 	}
 
@@ -66,9 +67,9 @@
 	return io_u->error;
 }
 
-static int fio_mmapio_sync(struct thread_data *td)
+static int fio_mmapio_sync(struct thread_data *td, struct fio_file *f)
 {
-	return msync(td->mmap, td->file_size, MS_SYNC);
+	return msync(f->mmap, f->file_size, MS_SYNC);
 }
 
 static void fio_mmapio_cleanup(struct thread_data *td)
diff --git a/engines/fio-engine-posixaio.c b/engines/fio-engine-posixaio.c
index 871db77..8cd3cf4 100644
--- a/engines/fio-engine-posixaio.c
+++ b/engines/fio-engine-posixaio.c
@@ -45,14 +45,15 @@
 	return sec + nsec;
 }
 
-static int fio_posixaio_sync(struct thread_data *td)
+static int fio_posixaio_sync(struct thread_data *td, struct fio_file *f)
 {
-	return fsync(td->fd);
+	return fsync(f->fd);
 }
 
 static int fio_posixaio_cancel(struct thread_data *td, struct io_u *io_u)
 {
-	int r = aio_cancel(td->fd, &io_u->aiocb);
+	struct fio_file *f = io_u->file;
+	int r = aio_cancel(f->fd, &io_u->aiocb);
 
 	if (r == 1 || r == AIO_CANCELED)
 		return 0;
@@ -63,8 +64,9 @@
 static int fio_posixaio_prep(struct thread_data *td, struct io_u *io_u)
 {
 	struct aiocb *aiocb = &io_u->aiocb;
+	struct fio_file *f = io_u->file;
 
-	aiocb->aio_fildes = td->fd;
+	aiocb->aio_fildes = f->fd;
 	aiocb->aio_buf = io_u->buf;
 	aiocb->aio_nbytes = io_u->buflen;
 	aiocb->aio_offset = io_u->offset;
diff --git a/engines/fio-engine-sg.c b/engines/fio-engine-sg.c
index 59eea1d..0db5ca9 100644
--- a/engines/fio-engine-sg.c
+++ b/engines/fio-engine-sg.c
@@ -61,8 +61,9 @@
 static int fio_sgio_getevents(struct thread_data *td, int min, int max,
 			      struct timespec fio_unused *t)
 {
+	struct fio_file *f = &td->files[0];
 	struct sgio_data *sd = td->io_ops->data;
-	struct pollfd pfd = { .fd = td->fd, .events = POLLIN };
+	struct pollfd pfd = { .fd = f->fd, .events = POLLIN };
 	void *buf = malloc(max * sizeof(struct sg_io_hdr));
 	int left = max, ret, events, i, r = 0, fl = 0;
 
@@ -70,8 +71,8 @@
 	 * don't block for !events
 	 */
 	if (!min) {
-		fl = fcntl(td->fd, F_GETFL);
-		fcntl(td->fd, F_SETFL, fl | O_NONBLOCK);
+		fl = fcntl(f->fd, F_GETFL);
+		fcntl(f->fd, F_SETFL, fl | O_NONBLOCK);
 	}
 
 	while (left) {
@@ -83,7 +84,7 @@
 				break;
 		} while (1);
 
-		ret = read(td->fd, buf, left * sizeof(struct sg_io_hdr));
+		ret = read(f->fd, buf, left * sizeof(struct sg_io_hdr));
 		if (ret < 0) {
 			if (errno == EAGAIN)
 				break;
@@ -105,33 +106,35 @@
 	}
 
 	if (!min)
-		fcntl(td->fd, F_SETFL, fl);
+		fcntl(f->fd, F_SETFL, fl);
 
 	free(buf);
 	return r;
 }
 
-static int fio_sgio_ioctl_doio(struct thread_data *td, struct io_u *io_u)
+static int fio_sgio_ioctl_doio(struct thread_data *td, struct fio_file *f,
+			       struct io_u *io_u)
 {
 	struct sgio_data *sd = td->io_ops->data;
 	struct sg_io_hdr *hdr = &io_u->hdr;
 
 	sd->events[0] = io_u;
 
-	return ioctl(td->fd, SG_IO, hdr);
+	return ioctl(f->fd, SG_IO, hdr);
 }
 
-static int fio_sgio_rw_doio(struct thread_data *td, struct io_u *io_u, int sync)
+static int fio_sgio_rw_doio(struct thread_data *td, struct fio_file *f,
+			    struct io_u *io_u, int sync)
 {
 	struct sg_io_hdr *hdr = &io_u->hdr;
 	int ret;
 
-	ret = write(td->fd, hdr, sizeof(*hdr));
+	ret = write(f->fd, hdr, sizeof(*hdr));
 	if (ret < 0)
 		return errno;
 
 	if (sync) {
-		ret = read(td->fd, hdr, sizeof(*hdr));
+		ret = read(f->fd, hdr, sizeof(*hdr));
 		if (ret < 0)
 			return errno;
 	}
@@ -141,13 +144,15 @@
 
 static int fio_sgio_doio(struct thread_data *td, struct io_u *io_u, int sync)
 {
-	if (td->filetype == FIO_TYPE_BD)
-		return fio_sgio_ioctl_doio(td, io_u);
+	struct fio_file *f = io_u->file;
 
-	return fio_sgio_rw_doio(td, io_u, sync);
+	if (td->filetype == FIO_TYPE_BD)
+		return fio_sgio_ioctl_doio(td, f, io_u);
+
+	return fio_sgio_rw_doio(td, f, io_u, sync);
 }
 
-static int fio_sgio_sync(struct thread_data *td)
+static int fio_sgio_sync(struct thread_data *td, struct fio_file *f)
 {
 	struct sgio_data *sd = td->io_ops->data;
 	struct sg_io_hdr *hdr;
@@ -266,6 +271,7 @@
 
 static int fio_sgio_init(struct thread_data *td)
 {
+	struct fio_file *f = &td->files[0];
 	struct sgio_data *sd;
 	unsigned int bs;
 	int ret;
@@ -276,14 +282,14 @@
 	td->io_ops->data = sd;
 
 	if (td->filetype == FIO_TYPE_BD) {
-		if (ioctl(td->fd, BLKSSZGET, &bs) < 0) {
+		if (ioctl(f->fd, BLKSSZGET, &bs) < 0) {
 			td_verror(td, errno);
 			return 1;
 		}
 	} else if (td->filetype == FIO_TYPE_CHAR) {
 		int version;
 
-		if (ioctl(td->fd, SG_GET_VERSION_NUM, &version) < 0) {
+		if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) {
 			td_verror(td, errno);
 			return 1;
 		}
diff --git a/engines/fio-engine-splice.c b/engines/fio-engine-splice.c
index 30984f1..4f5b86c 100644
--- a/engines/fio-engine-splice.c
+++ b/engines/fio-engine-splice.c
@@ -16,9 +16,9 @@
 	int pipe[2];
 };
 
-static int fio_spliceio_sync(struct thread_data *td)
+static int fio_spliceio_sync(struct thread_data *td, struct fio_file *f)
 {
-	return fsync(td->fd);
+	return fsync(f->fd);
 }
 
 static int fio_spliceio_getevents(struct thread_data *td, int fio_unused min,
@@ -53,6 +53,7 @@
 static int fio_splice_read(struct thread_data *td, struct io_u *io_u)
 {
 	struct spliceio_data *sd = td->io_ops->data;
+	struct fio_file *f = io_u->file;
 	int ret, ret2, buflen;
 	off_t offset;
 	void *p;
@@ -66,7 +67,7 @@
 		if (this_len > SPLICE_DEF_SIZE)
 			this_len = SPLICE_DEF_SIZE;
 
-		ret = splice(td->fd, &offset, sd->pipe[1], NULL, this_len, SPLICE_F_MORE);
+		ret = splice(f->fd, &offset, sd->pipe[1], NULL, this_len, SPLICE_F_MORE);
 		if (ret < 0) {
 			if (errno == ENODATA || errno == EAGAIN)
 				continue;
@@ -103,6 +104,7 @@
 		}
 	};
 	struct pollfd pfd = { .fd = sd->pipe[1], .events = POLLOUT, };
+	struct fio_file *f = io_u->file;
 	off_t off = io_u->offset;
 	int ret, ret2;
 
@@ -118,7 +120,7 @@
 		iov[0].iov_base += ret;
 
 		while (ret) {
-			ret2 = splice(sd->pipe[0], NULL, td->fd, &off, ret, 0);
+			ret2 = splice(sd->pipe[0], NULL, f->fd, &off, ret, 0);
 			if (ret2 < 0)
 				return errno;
 
diff --git a/engines/fio-engine-sync.c b/engines/fio-engine-sync.c
index abc29f4..1806d4d 100644
--- a/engines/fio-engine-sync.c
+++ b/engines/fio-engine-sync.c
@@ -14,9 +14,9 @@
 	struct io_u *last_io_u;
 };
 
-static int fio_syncio_sync(struct thread_data *td)
+static int fio_syncio_sync(struct thread_data *td, struct fio_file *f)
 {
-	return fsync(td->fd);
+	return fsync(f->fd);
 }
 
 static int fio_syncio_getevents(struct thread_data *td, int fio_unused min,
@@ -45,7 +45,9 @@
 
 static int fio_syncio_prep(struct thread_data *td, struct io_u *io_u)
 {
-	if (lseek(td->fd, io_u->offset, SEEK_SET) == -1) {
+	struct fio_file *f = io_u->file;
+
+	if (lseek(f->fd, io_u->offset, SEEK_SET) == -1) {
 		td_verror(td, errno);
 		return 1;
 	}
@@ -56,12 +58,13 @@
 static int fio_syncio_queue(struct thread_data *td, struct io_u *io_u)
 {
 	struct syncio_data *sd = td->io_ops->data;
+	struct fio_file *f = io_u->file;
 	int ret;
 
 	if (io_u->ddir == DDIR_READ)
-		ret = read(td->fd, io_u->buf, io_u->buflen);
+		ret = read(f->fd, io_u->buf, io_u->buflen);
 	else
-		ret = write(td->fd, io_u->buf, io_u->buflen);
+		ret = write(f->fd, io_u->buf, io_u->buflen);
 
 	if ((unsigned int) ret != io_u->buflen) {
 		if (ret > 0) {