Add more context to the error messages

Errors like:

fio: pid=0, err=22/file:filesetup.c:380, error=Invalid argument

do not give a lot of clue as to what is wrong, unless you
have a matching source. So add a context relevant info
message as well.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/engines/cpu.c b/engines/cpu.c
index 27ec6da..6ad547b 100644
--- a/engines/cpu.c
+++ b/engines/cpu.c
@@ -9,7 +9,7 @@
 static int fio_cpuio_init(struct thread_data *td)
 {
 	if (!td->cpuload) {
-		td_vmsg(td, EINVAL, "cpu thread needs rate");
+		td_vmsg(td, EINVAL, "cpu thread needs rate", "cpu_load");
 		return 1;
 	} else if (td->cpuload > 100)
 		td->cpuload = 100;
diff --git a/engines/libaio.c b/engines/libaio.c
index a659ba9..bd702e3 100644
--- a/engines/libaio.c
+++ b/engines/libaio.c
@@ -178,7 +178,7 @@
 
 	memset(ld, 0, sizeof(*ld));
 	if (io_queue_init(td->iodepth, &ld->aio_ctx)) {
-		td_verror(td, errno);
+		td_verror(td, errno, "io_queue_init");
 		free(ld);
 		return 1;
 	}
diff --git a/engines/mmap.c b/engines/mmap.c
index 08bbd99..d429914 100644
--- a/engines/mmap.c
+++ b/engines/mmap.c
@@ -37,7 +37,7 @@
 	}
 
 	if (io_u->error)
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "sync");
 
 	return FIO_Q_COMPLETED;
 }
@@ -56,7 +56,7 @@
 	 */
 	for_each_file(td, f, i) {
 		if (ftruncate(f->fd, f->file_size) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "ftruncate");
 			return 1;
 		}
 	}
diff --git a/engines/net.c b/engines/net.c
index 381c731..55b2128 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -25,7 +25,7 @@
 	 */
 	if ((send_to_net(td) && io_u->ddir == DDIR_READ) ||
 	    (!send_to_net(td) && io_u->ddir == DDIR_WRITE)) {
-		td_verror(td, EINVAL);
+		td_verror(td, EINVAL, "bad direction");
 		return 1;
 	}
 		
@@ -38,7 +38,7 @@
 	 * If offset is different from last end position, it's a seek.
 	 * As network io is purely sequential, we don't allow seeks.
 	 */
-	td_verror(td, EINVAL);
+	td_verror(td, EINVAL, "cannot seek");
 	return 1;
 }
 
@@ -72,7 +72,7 @@
 	}
 
 	if (io_u->error)
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "xfer");
 
 	return FIO_Q_COMPLETED;
 }
@@ -93,7 +93,7 @@
 
 		hent = gethostbyname(host);
 		if (!hent) {
-			td_verror(td, errno);
+			td_verror(td, errno, "gethostbyname");
 			return 1;
 		}
 
@@ -103,12 +103,12 @@
 	for_each_file(td, f, i) {
 		f->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 		if (f->fd < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "socket");
 			return 1;
 		}
 
 		if (connect(f->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "connect");
 			return 1;
 		}
 	}
@@ -142,7 +142,7 @@
 			if (errno == EINTR)
 				continue;
 
-			td_verror(td, errno);
+			td_verror(td, errno, "poll");
 			break;
 		} else if (!ret)
 			continue;
@@ -159,7 +159,7 @@
 
 			f->fd = accept(fd, (struct sockaddr *) addr, &socklen);
 			if (f->fd < 0) {
-				td_verror(td, errno);
+				td_verror(td, errno, "accept");
 				return 1;
 			}
 			accepts++;
@@ -177,18 +177,18 @@
 
 	fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 	if (fd < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "socket");
 		return 1;
 	}
 
 	opt = 1;
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "setsockopt");
 		return 1;
 	}
 #ifdef SO_REUSEPORT
 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "setsockopt");
 		return 1;
 	}
 #endif
@@ -199,11 +199,11 @@
 	addr.sin_port = htons(port);
 
 	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "bind");
 		return 1;
 	}
 	if (listen(fd, 1) < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "listen");
 		return 1;
 	}
 
diff --git a/engines/posixaio.c b/engines/posixaio.c
index a56ab3a..ebd6faf 100644
--- a/engines/posixaio.c
+++ b/engines/posixaio.c
@@ -153,7 +153,7 @@
 
 	if (ret) {
 		io_u->error = errno;
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "xfer");
 		return FIO_Q_COMPLETED;
 	}
 
diff --git a/engines/sg.c b/engines/sg.c
index f955c20..b9033b8 100644
--- a/engines/sg.c
+++ b/engines/sg.c
@@ -97,7 +97,7 @@
 			if (ret < 0) {
 				if (!r)
 					r = -errno;
-				td_verror(td, errno);
+				td_verror(td, errno, "poll");
 				break;
 			} else if (!ret)
 				continue;
@@ -118,7 +118,7 @@
 				if (errno == EAGAIN)
 					continue;
 				r = -errno;
-				td_verror(td, errno);
+				td_verror(td, errno, "read");
 				break;
 			} else if (ret) {
 				p += ret;
@@ -253,7 +253,7 @@
 	}
 
 	if (io_u->error) {
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "xfer");
 		return FIO_Q_COMPLETED;
 	}
 
@@ -339,14 +339,14 @@
 
 	if (td->filetype == FIO_TYPE_BD) {
 		if (ioctl(f->fd, BLKSSZGET, &bs) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "ioctl");
 			goto err;
 		}
 	} else if (td->filetype == FIO_TYPE_CHAR) {
 		int version;
 
 		if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "ioctl");
 			goto err;
 		}
 
diff --git a/engines/splice.c b/engines/splice.c
index 5c4411c..a20f4e0 100644
--- a/engines/splice.c
+++ b/engines/splice.c
@@ -125,7 +125,7 @@
 	}
 
 	if (io_u->error)
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "xfer");
 
 	return FIO_Q_COMPLETED;
 }
@@ -147,7 +147,7 @@
 	struct spliceio_data *sd = malloc(sizeof(*sd));
 
 	if (pipe(sd->pipe) < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "pipe");
 		free(sd);
 		return 1;
 	}
diff --git a/engines/sync.c b/engines/sync.c
index 5cf7366..ad02e09 100644
--- a/engines/sync.c
+++ b/engines/sync.c
@@ -21,7 +21,7 @@
 		return 0;
 
 	if (lseek(f->fd, io_u->offset, SEEK_SET) == -1) {
-		td_verror(td, errno);
+		td_verror(td, errno, "lseek");
 		return 1;
 	}
 
@@ -50,7 +50,7 @@
 	}
 
 	if (io_u->error)
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "xfer");
 
 	return FIO_Q_COMPLETED;
 }
diff --git a/engines/syslet-rw.c b/engines/syslet-rw.c
index f188d1c..d439810 100644
--- a/engines/syslet-rw.c
+++ b/engines/syslet-rw.c
@@ -190,7 +190,7 @@
 	assert(sd->nr_events < td->iodepth);
 
 	if (io_u->error)
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "xfer");
 
 	return FIO_Q_COMPLETED;
 }
diff --git a/filesetup.c b/filesetup.c
index 0874224..4cd62d6 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -41,17 +41,17 @@
 
 	f->fd = open(f->file_name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
 	if (f->fd < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "open");
 		return 1;
 	}
 
 	if (ftruncate(f->fd, f->file_size) == -1) {
-		td_verror(td, errno);
+		td_verror(td, errno, "ftruncate");
 		goto err;
 	}
 
 	if (posix_fallocate(f->fd, 0, f->file_size) < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "posix_fallocate");
 		goto err;
 	}
 
@@ -71,9 +71,9 @@
 			continue;
 		} else {
 			if (r < 0)
-				td_verror(td, errno);
+				td_verror(td, errno, "write");
 			else
-				td_verror(td, EIO);
+				td_verror(td, EIO, "write");
 
 			break;
 		}
@@ -128,7 +128,7 @@
 
 	if (!td->total_file_size) {
 		log_err("Need size for create\n");
-		td_verror(td, EINVAL);
+		td_verror(td, EINVAL, "file_size");
 		return 1;
 	}
 
@@ -172,7 +172,7 @@
 
 	if (td->overwrite) {
 		if (fstat(f->fd, &st) == -1) {
-			td_verror(td, errno);
+			td_verror(td, errno, "fstat");
 			return 1;
 		}
 
@@ -193,7 +193,7 @@
 
 	r = blockdev_size(f->fd, &bytes);
 	if (r) {
-		td_verror(td, r);
+		td_verror(td, r, "blockdev_size");
 		return 1;
 	}
 
@@ -248,7 +248,7 @@
 		ret = 0;
 
 	if (ret < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "invalidate_cache");
 		return 1;
 	}
 
@@ -272,7 +272,7 @@
 	f->mmap = mmap(NULL, f->file_size, flags, MAP_SHARED, f->fd, f->file_offset);
 	if (f->mmap == MAP_FAILED) {
 		f->mmap = NULL;
-		td_verror(td, errno);
+		td_verror(td, errno, "mmap");
 		return 1;
 	}
 
@@ -281,12 +281,12 @@
 
 	if (td->sequential) {
 		if (madvise(f->mmap, f->file_size, MADV_SEQUENTIAL) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "madvise");
 			return 1;
 		}
 	} else {
 		if (madvise(f->mmap, f->file_size, MADV_RANDOM) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "madvise");
 			return 1;
 		}
 	}
@@ -315,12 +315,12 @@
 
 	if (td->sequential) {
 		if (fadvise(f->fd, f->file_offset, f->file_size, POSIX_FADV_SEQUENTIAL) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "fadvise");
 			return 1;
 		}
 	} else {
 		if (fadvise(f->fd, f->file_offset, f->file_size, POSIX_FADV_RANDOM) < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "fadvise");
 			return 1;
 		}
 	}
@@ -383,7 +383,11 @@
 	}
 
 	if (f->fd == -1) {
-		td_verror(td, errno);
+		int __e = errno;
+
+		td_verror(td, __e, "open");
+		if (__e == EINVAL && td->odirect)
+			log_err("fio: destinations does not support O_DIRECT\n");
 		return 1;
 	}
 
@@ -446,7 +450,7 @@
 	td->io_size = td->total_file_size;
 	if (td->io_size == 0) {
 		log_err("%s: no io blocks\n", td->name);
-		td_verror(td, EINVAL);
+		td_verror(td, EINVAL, "total_file_size");
 		return 1;
 	}
 
diff --git a/fio.c b/fio.c
index 0e1eadb..9206393 100644
--- a/fio.c
+++ b/fio.c
@@ -203,7 +203,7 @@
 requeue:
 	ret = td_io_queue(td, io_u);
 	if (ret < 0) {
-		td_verror(td, io_u->error);
+		td_verror(td, io_u->error, "td_io_queue");
 		put_io_u(td, io_u);
 		return 1;
 	} else if (ret == FIO_Q_QUEUED) {
@@ -211,7 +211,7 @@
 			return 1;
 	} else if (ret == FIO_Q_COMPLETED) {
 		if (io_u->error) {
-			td_verror(td, io_u->error);
+			td_verror(td, io_u->error, "td_io_queue");
 			return 1;
 		}
 
@@ -298,7 +298,7 @@
 			break;
 		default:
 			assert(ret < 0);
-			td_verror(td, -ret);
+			td_verror(td, -ret, "td_io_queue");
 			break;
 		}
 
@@ -463,7 +463,7 @@
 		if (check_min_rate(td, &comp_time)) {
 			if (exitall_on_terminate)
 				terminate_threads(td->groupid, 0);
-			td_verror(td, ENODATA);
+			td_verror(td, ENODATA, "check_min_rate");
 			break;
 		}
 
@@ -585,7 +585,7 @@
 
 	f = fopen(tmp, "r+");
 	if (!f) {
-		td_verror(td, errno);
+		td_verror(td, errno, "fopen");
 		return 1;
 	}
 
@@ -594,7 +594,7 @@
 	 */
 	ret = fwrite(td->ioscheduler, strlen(td->ioscheduler), 1, f);
 	if (ferror(f) || ret != 1) {
-		td_verror(td, errno);
+		td_verror(td, errno, "fwrite");
 		fclose(f);
 		return 1;
 	}
@@ -606,7 +606,7 @@
 	 */
 	ret = fread(tmp, 1, sizeof(tmp), f);
 	if (ferror(f) || ret < 0) {
-		td_verror(td, errno);
+		td_verror(td, errno, "fread");
 		fclose(f);
 		return 1;
 	}
@@ -614,7 +614,7 @@
 	sprintf(tmp2, "[%s]", td->ioscheduler);
 	if (!strstr(tmp, tmp2)) {
 		log_err("fio: io scheduler %s not found\n", td->ioscheduler);
-		td_verror(td, EINVAL);
+		td_verror(td, EINVAL, "iosched_switch");
 		fclose(f);
 		return 1;
 	}
@@ -670,7 +670,7 @@
 		goto err;
 
 	if (fio_setaffinity(td) == -1) {
-		td_verror(td, errno);
+		td_verror(td, errno, "cpu_set_affinity");
 		goto err;
 	}
 
@@ -679,13 +679,13 @@
 
 	if (td->ioprio) {
 		if (ioprio_set(IOPRIO_WHO_PROCESS, 0, td->ioprio) == -1) {
-			td_verror(td, errno);
+			td_verror(td, errno, "ioprio_set");
 			goto err;
 		}
 	}
 
 	if (nice(td->nice) == -1) {
-		td_verror(td, errno);
+		td_verror(td, errno, "nice");
 		goto err;
 	}
 
diff --git a/fio.h b/fio.h
index 7a4b1d1..959e52f 100644
--- a/fio.h
+++ b/fio.h
@@ -443,18 +443,20 @@
 #define IO_U_TIMEOUT_INC	5
 #define IO_U_TIMEOUT		30
 
-#define __td_verror(td, err, msg)					\
+#define __td_verror(td, err, msg, func)					\
 	do {								\
 		if ((td)->error)					\
 			break;						\
 		int e = (err);						\
 		(td)->error = e;					\
-		snprintf(td->verror, sizeof(td->verror) - 1, "file:%s:%d, error=%s", __FILE__, __LINE__, (msg));	\
+		snprintf(td->verror, sizeof(td->verror) - 1, "file:%s:%d, func=%s, error=%s", __FILE__, __LINE__, (func), (msg));	\
 	} while (0)
 
 
-#define td_verror(td, err)	__td_verror((td), (err), strerror((err)))
-#define td_vmsg(td, err, msg)	__td_verror((td), (err), (msg))
+#define td_verror(td, err, func)	\
+	__td_verror((td), (err), strerror((err)), (func))
+#define td_vmsg(td, err, msg, func)	\
+	__td_verror((td), (err), (msg), (func))
 
 extern int exitall_on_terminate;
 extern int thread_number;
diff --git a/init.c b/init.c
index a235e2f..c8f27ad 100644
--- a/init.c
+++ b/init.c
@@ -725,7 +725,7 @@
 		if (td->directory && td->directory[0] != '\0') {
 			if (lstat(td->directory, &sb) < 0) {
 				log_err("fio: %s is not a directory\n", td->directory);
-				td_verror(td, errno);
+				td_verror(td, errno, "lstat");
 				return 1;
 			}
 			if (!S_ISDIR(sb.st_mode)) {
@@ -850,12 +850,12 @@
 
 	fd = open("/dev/urandom", O_RDONLY);
 	if (fd == -1) {
-		td_verror(td, errno);
+		td_verror(td, errno, "open");
 		return 1;
 	}
 
 	if (read(fd, seeds, sizeof(seeds)) < (int) sizeof(seeds)) {
-		td_verror(td, EIO);
+		td_verror(td, EIO, "read");
 		close(fd);
 		return 1;
 	}
diff --git a/io_u.c b/io_u.c
index c938960..8141991 100644
--- a/io_u.c
+++ b/io_u.c
@@ -548,7 +548,7 @@
 	if (min_events > 0) {
 		ret = td_io_commit(td);
 		if (ret < 0) {
-			td_verror(td, -ret);
+			td_verror(td, -ret, "td_io_commit");
 			return ret;
 		}
 	} else {
@@ -559,7 +559,7 @@
 
 	ret = td_io_getevents(td, min_events, td->cur_depth, tvp);
 	if (ret < 0) {
-		td_verror(td, -ret);
+		td_verror(td, -ret, "td_io_getevents");
 		return ret;
 	} else if (!ret)
 		return ret;
diff --git a/ioengines.c b/ioengines.c
index 441f36f..0b3ec16 100644
--- a/ioengines.c
+++ b/ioengines.c
@@ -102,7 +102,7 @@
 	dlerror();
 	dlhandle = dlopen(engine_lib, RTLD_LAZY);
 	if (!dlhandle) {
-		td_vmsg(td, -1, dlerror());
+		td_vmsg(td, -1, dlerror(), "dlopen");
 		return NULL;
 	}
 
@@ -112,7 +112,7 @@
 	 */
 	ops = dlsym(dlhandle, "ioengine");
 	if (!ops) {
-		td_vmsg(td, -1, dlerror());
+		td_vmsg(td, -1, dlerror(), "dlsym");
 		dlclose(dlhandle);
 		return NULL;
 	}
@@ -234,6 +234,8 @@
 
 int td_io_commit(struct thread_data *td)
 {
+	if (!td->cur_depth)
+		return 0;
 	if (td->io_ops->commit)
 		return td->io_ops->commit(td);
 
diff --git a/memory.c b/memory.c
index 079c076..d9cfe9b 100644
--- a/memory.c
+++ b/memory.c
@@ -69,14 +69,14 @@
 
 		td->shm_id = shmget(IPC_PRIVATE, td->orig_buffer_size, flags);
 		if (td->shm_id < 0) {
-			td_verror(td, errno);
+			td_verror(td, errno, "shmget");
 			perror("shmget");
 			return 1;
 		}
 
 		td->orig_buffer = shmat(td->shm_id, NULL, 0);
 		if (td->orig_buffer == (void *) -1) {
-			td_verror(td, errno);
+			td_verror(td, errno, "shmat");
 			perror("shmat");
 			td->orig_buffer = NULL;
 			return 1;
@@ -90,7 +90,7 @@
 			td->mmapfd = open(td->mmapfile, O_RDWR|O_CREAT, 0644);
 
 			if (td->mmapfd < 0) {
-				td_verror(td, errno);
+				td_verror(td, errno, "open");
 				perror("open mmap file");
 				td->orig_buffer = NULL;
 				return 1;
@@ -100,7 +100,7 @@
 
 		td->orig_buffer = mmap(NULL, td->orig_buffer_size, PROT_READ | PROT_WRITE, flags, td->mmapfd, 0);
 		if (td->orig_buffer == MAP_FAILED) {
-			td_verror(td, errno);
+			td_verror(td, errno, "mmap");
 			perror("mmap");
 			td->orig_buffer = NULL;
 			if (td->mmapfd) {