Merge branch 'master' into gfio

Conflicts:
	eta.c

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/Makefile b/Makefile
index 5d4e3e7..ea8c851 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-CC	= gcc
+CC	?= gcc
 DEBUGFLAGS = -D_FORTIFY_SOURCE=2 -DFIO_INC_DEBUG
 CPPFLAGS= -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 \
 	$(DEBUGFLAGS)
diff --git a/backend.c b/backend.c
index dcc6fba..f20857a 100644
--- a/backend.c
+++ b/backend.c
@@ -1631,7 +1631,7 @@
 
 	setup_disk_util();
 
-	disk_thread_mutex = fio_mutex_init(0);
+	disk_thread_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
 
 	ret = pthread_create(&disk_util_thread, NULL, disk_thread_main, NULL);
 	if (ret) {
@@ -1672,10 +1672,10 @@
 		setup_log(&agg_io_log[DDIR_WRITE], 0, IO_LOG_TYPE_BW);
 	}
 
-	startup_mutex = fio_mutex_init(0);
+	startup_mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
 	if (startup_mutex == NULL)
 		return 1;
-	writeout_mutex = fio_mutex_init(1);
+	writeout_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 	if (writeout_mutex == NULL)
 		return 1;
 
diff --git a/cgroup.c b/cgroup.c
index ea6bbd6..86d4d5e 100644
--- a/cgroup.c
+++ b/cgroup.c
@@ -182,7 +182,7 @@
 
 static void fio_init cgroup_init(void)
 {
-	lock = fio_mutex_init(1);
+	lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 }
 
 static void fio_exit cgroup_exit(void)
diff --git a/diskutil.c b/diskutil.c
index 32616b7..a3a5b4d 100644
--- a/diskutil.c
+++ b/diskutil.c
@@ -132,13 +132,18 @@
 	struct flist_head *entry;
 	struct disk_util *du;
 
+	fio_mutex_down(disk_util_mutex);
+
 	flist_for_each(entry, &disk_list) {
 		du = flist_entry(entry, struct disk_util, list);
 
-		if (major == du->major && minor == du->minor)
+		if (major == du->major && minor == du->minor) {
+			fio_mutex_up(disk_util_mutex);
 			return du;
+		}
 	}
 
+	fio_mutex_up(disk_util_mutex);
 	return NULL;
 }
 
@@ -285,7 +290,7 @@
 	du->minor = mindev;
 	INIT_FLIST_HEAD(&du->slavelist);
 	INIT_FLIST_HEAD(&du->slaves);
-	du->lock = fio_mutex_init(1);
+	du->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 	du->users = 0;
 
 	fio_mutex_down(disk_util_mutex);
@@ -308,8 +313,9 @@
 	get_io_ticks(du, &du->last_dus);
 
 	flist_add_tail(&du->list, &disk_list);
-	find_add_disk_slaves(td, path, du);
 	fio_mutex_up(disk_util_mutex);
+
+	find_add_disk_slaves(td, path, du);
 	return du;
 }
 
@@ -618,5 +624,5 @@
 
 void setup_disk_util(void)
 {
-	disk_util_mutex = fio_mutex_init(1);
+	disk_util_mutex = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 }
diff --git a/eta.c b/eta.c
index 34afe0c..e1050b5 100644
--- a/eta.c
+++ b/eta.c
@@ -285,14 +285,18 @@
 		    || td->runstate == TD_FSYNCING
 		    || td->runstate == TD_PRE_READING) {
 			je->nr_running++;
-			je->t_rate[0] += td->o.rate[0];
-			je->t_rate[1] += td->o.rate[1];
-			je->m_rate[0] += td->o.ratemin[0];
-			je->m_rate[1] += td->o.ratemin[1];
-			je->t_iops[0] += td->o.rate_iops[0];
-			je->t_iops[1] += td->o.rate_iops[1];
-			je->m_iops[0] += td->o.rate_iops_min[0];
-			je->m_iops[1] += td->o.rate_iops_min[1];
+			if (td_read(td)) {
+				je->t_rate[0] += td->o.rate[DDIR_READ];
+				je->t_iops[0] += td->o.rate_iops[DDIR_READ];
+				je->m_rate[0] += td->o.ratemin[DDIR_READ];
+				je->m_iops[0] += td->o.rate_iops_min[DDIR_READ];
+			}
+			if (td_write(td)) {
+				je->t_rate[1] += td->o.rate[DDIR_WRITE];
+				je->t_iops[1] += td->o.rate_iops[DDIR_WRITE];
+				je->m_rate[1] += td->o.ratemin[DDIR_WRITE];
+				je->m_iops[1] += td->o.rate_iops_min[DDIR_WRITE];
+			}
 			je->files_open += td->nr_open_files;
 		} else if (td->runstate == TD_RAMP) {
 			je->nr_running++;
diff --git a/file.h b/file.h
index 51df839..68f9a6e 100644
--- a/file.h
+++ b/file.h
@@ -147,6 +147,7 @@
 struct thread_data;
 extern void close_files(struct thread_data *);
 extern void close_and_free_files(struct thread_data *);
+extern unsigned long long get_start_offset(struct thread_data *);
 extern int __must_check setup_files(struct thread_data *);
 extern int __must_check file_invalidate_cache(struct thread_data *, struct fio_file *);
 extern int __must_check generic_open_file(struct thread_data *, struct fio_file *);
diff --git a/filehash.c b/filehash.c
index 1bb1eb2..392464e 100644
--- a/filehash.c
+++ b/filehash.c
@@ -107,5 +107,5 @@
 	for (i = 0; i < HASH_BUCKETS; i++)
 		INIT_FLIST_HEAD(&file_hash[i]);
 
-	hash_lock = fio_mutex_init(1);
+	hash_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 }
diff --git a/filesetup.c b/filesetup.c
index 76e142a..9c486be 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -657,6 +657,12 @@
 	return ret;
 }
 
+unsigned long long get_start_offset(struct thread_data *td)
+{
+	return td->o.start_offset +
+		(td->thread_number - 1) * td->o.offset_increment;
+}
+
 /*
  * Open the files and setup files sizes, creating files if necessary.
  */
@@ -718,8 +724,7 @@
 	extend_size = total_size = 0;
 	need_extend = 0;
 	for_each_file(td, f, i) {
-		f->file_offset = td->o.start_offset +
-			(td->thread_number - 1) * td->o.offset_increment;
+		f->file_offset = get_start_offset(td);
 
 		if (!td->o.file_size_low) {
 			/*
@@ -1006,7 +1011,7 @@
 		f->lock = fio_mutex_rw_init();
 		break;
 	case FILE_LOCK_EXCLUSIVE:
-		f->lock = fio_mutex_init(1);
+		f->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 		break;
 	default:
 		log_err("fio: unknown lock mode: %d\n", td->o.file_lock_mode);
diff --git a/flow.c b/flow.c
index bf5eeec..2993f4e 100644
--- a/flow.c
+++ b/flow.c
@@ -92,7 +92,7 @@
 
 void flow_init(void)
 {
-	flow_lock = fio_mutex_init(1);
+	flow_lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 	flow_list = smalloc(sizeof(*flow_list));
 	INIT_FLIST_HEAD(flow_list);
 }
diff --git a/gettime.c b/gettime.c
index e8f5ab5..5b49287 100644
--- a/gettime.c
+++ b/gettime.c
@@ -304,7 +304,7 @@
 	pthread_attr_t attr;
 	int ret;
 
-	mutex = fio_mutex_init(0);
+	mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
 	if (!mutex)
 		return 1;
 
diff --git a/init.c b/init.c
index 4f42a5c..2b581fb 100644
--- a/init.c
+++ b/init.c
@@ -810,7 +810,7 @@
 			f->real_file_size = -1ULL;
 	}
 
-	td->mutex = fio_mutex_init(0);
+	td->mutex = fio_mutex_init(FIO_MUTEX_LOCKED);
 
 	td->ts.clat_percentiles = td->o.clat_percentiles;
 	if (td->o.overwrite_plist)
diff --git a/io_u.c b/io_u.c
index 7e05ff9..28a86f7 100644
--- a/io_u.c
+++ b/io_u.c
@@ -256,7 +256,7 @@
 {
 	assert(ddir_rw(ddir));
 
-	if (f->last_pos >= f->io_size && td->o.time_based)
+	if (f->last_pos >= f->io_size + get_start_offset(td) && td->o.time_based)
 		f->last_pos = f->last_pos - f->io_size;
 
 	if (f->last_pos < f->real_file_size) {
@@ -377,7 +377,7 @@
 {
 	struct fio_file *f = io_u->file;
 
-	return io_u->offset + buflen <= f->io_size + td->o.start_offset;
+	return io_u->offset + buflen <= f->io_size + get_start_offset(td);
 }
 
 static unsigned int __get_next_buflen(struct thread_data *td, struct io_u *io_u)
diff --git a/mutex.h b/mutex.h
index 5938e95..6fdf7c6 100644
--- a/mutex.h
+++ b/mutex.h
@@ -10,6 +10,11 @@
 	int waiters;
 };
 
+enum {
+	FIO_MUTEX_LOCKED	= 0,
+	FIO_MUTEX_UNLOCKED	= 1,
+};
+
 extern struct fio_mutex *fio_mutex_init(int);
 extern void fio_mutex_remove(struct fio_mutex *);
 extern void fio_mutex_down(struct fio_mutex *);
diff --git a/os/windows/posix.c b/os/windows/posix.c
index 41bcb2d..bfffe77 100755
--- a/os/windows/posix.c
+++ b/os/windows/posix.c
@@ -20,6 +20,9 @@
 
 #include "../os-windows.h"
 
+extern unsigned long mtime_since_now(struct timeval *);
+extern void fio_gettime(struct timeval *, void *);
+
 long sysconf(int name)
 {
 	long long val = -1;
@@ -95,8 +98,8 @@
 int gettimeofday(struct timeval *restrict tp, void *restrict tzp)
 {
 	FILETIME fileTime;
-	unsigned long long unix_time, windows_time;
-	const time_t MILLISECONDS_BETWEEN_1601_AND_1970 = 11644473600000;
+	uint64_t unix_time, windows_time;
+	const uint64_t MILLISECONDS_BETWEEN_1601_AND_1970 = 11644473600000;
 
 	/* Ignore the timezone parameter */
 	(void)tzp;
@@ -107,7 +110,7 @@
 	 * Its precision is 100 ns but accuracy is only one clock tick, or normally around 15 ms.
 	 */
 	GetSystemTimeAsFileTime(&fileTime);
-	windows_time = ((unsigned long long)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
+	windows_time = ((uint64_t)fileTime.dwHighDateTime << 32) + fileTime.dwLowDateTime;
 	/* Divide by 10,000 to convert to ms and subtract the time between 1601 and 1970 */
 	unix_time = (((windows_time)/10000) - MILLISECONDS_BETWEEN_1601_AND_1970);
 	/* unix_time is now the number of milliseconds since 1970 (the Unix epoch) */
@@ -264,7 +267,7 @@
 		tp->tv_sec = counts.QuadPart / freq.QuadPart;
 		/* Get the difference between the number of ns stored
 		 * in 'tv_sec' and that stored in 'counts' */
-		unsigned long long t = tp->tv_sec * freq.QuadPart;
+		uint64_t t = tp->tv_sec * freq.QuadPart;
 		t = counts.QuadPart - t;
 		/* 't' now contains the number of cycles since the last second.
 		 * We want the number of nanoseconds, so multiply out by 1,000,000,000
@@ -321,17 +324,17 @@
 
 	i = strlen(path) - 1;
 
-	while (name[i] != '\\' && name[i] != '/' && i >= 0)
+	while (path[i] != '\\' && path[i] != '/' && i >= 0)
 		i--;
 
-	strcpy(name, path + i);
+	strncpy(name, path + i + 1, MAX_PATH);
 
 	return name;
 }
 
 int posix_fallocate(int fd, off_t offset, off_t len)
 {
-	const int BUFFER_SIZE = 64*1024*1024;
+	const int BUFFER_SIZE = 64 * 1024 * 1024;
 	int rc = 0;
 	char *buf;
 	unsigned int write_len;
@@ -348,7 +351,9 @@
 
 	memset(buf, 0, BUFFER_SIZE);
 
-	if (lseek(fd, offset, SEEK_SET) == -1)
+	int64_t prev_pos = _telli64(fd);
+
+	if (_lseeki64(fd, offset, SEEK_SET) == -1)
 		return errno;
 
 	while (bytes_remaining > 0) {
@@ -367,17 +372,18 @@
 	}
 
 	free(buf);
+	_lseeki64(fd, prev_pos, SEEK_SET);
 	return rc;
 }
 
 int ftruncate(int fildes, off_t length)
 {
 	BOOL bSuccess;
-	int old_pos = tell(fildes);
-	lseek(fildes, length, SEEK_SET);
+	int64_t prev_pos = _telli64(fildes);
+	_lseeki64(fildes, length, SEEK_SET);
 	HANDLE hFile = (HANDLE)_get_osfhandle(fildes);
 	bSuccess = SetEndOfFile(hFile);
-	lseek(fildes, old_pos, SEEK_SET);
+	_lseeki64(fildes, prev_pos, SEEK_SET);
 	return !bSuccess;
 }
 
@@ -459,7 +465,7 @@
 
 int getrusage(int who, struct rusage *r_usage)
 {
-	const time_t SECONDS_BETWEEN_1601_AND_1970 = 11644473600;
+	const uint64_t SECONDS_BETWEEN_1601_AND_1970 = 11644473600;
 	FILETIME cTime, eTime, kTime, uTime;
 	time_t time;
 
@@ -467,14 +473,14 @@
 
 	HANDLE hProcess = GetCurrentProcess();
 	GetProcessTimes(hProcess, &cTime, &eTime, &kTime, &uTime);
-	time = ((unsigned long long)uTime.dwHighDateTime << 32) + uTime.dwLowDateTime;
+	time = ((uint64_t)uTime.dwHighDateTime << 32) + uTime.dwLowDateTime;
 	/* Divide by 10,000,000 to get the number of seconds and move the epoch from
 	 * 1601 to 1970 */
 	time = (time_t)(((time)/10000000) - SECONDS_BETWEEN_1601_AND_1970);
 	r_usage->ru_utime.tv_sec = time;
 	/* getrusage() doesn't care about anything other than seconds, so set tv_usec to 0 */
 	r_usage->ru_utime.tv_usec = 0;
-	time = ((unsigned long long)kTime.dwHighDateTime << 32) + kTime.dwLowDateTime;
+	time = ((uint64_t)kTime.dwHighDateTime << 32) + kTime.dwLowDateTime;
 	/* Divide by 10,000,000 to get the number of seconds and move the epoch from
 	 * 1601 to 1970 */
 	time = (time_t)(((time)/10000000) - SECONDS_BETWEEN_1601_AND_1970);
@@ -505,17 +511,17 @@
 ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
 		off_t offset)
 {
-	long pos = tell(fildes);
-	ssize_t len = write(fildes, buf, nbyte);
-	lseek(fildes, pos, SEEK_SET);
+	int64_t pos = _telli64(fildes);
+	ssize_t len = _write(fildes, buf, nbyte);
+	_lseeki64(fildes, pos, SEEK_SET);
 	return len;
 }
 
 ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset)
 {
-	long pos = tell(fildes);
+	int64_t pos = _telli64(fildes);
 	ssize_t len = read(fildes, buf, nbyte);
-	lseek(fildes, pos, SEEK_SET);
+	_lseeki64(fildes, pos, SEEK_SET);
 	return len;
 }
 
@@ -631,9 +637,30 @@
 
 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
 {
-	log_err("%s is not implemented\n", __func__);
-	errno = ENOSYS;
-	return -1;
+	struct timeval tv;
+	DWORD ms_remaining;
+	DWORD ms_total = (rqtp->tv_sec * 1000) + (rqtp->tv_nsec / 1000000.0);
+
+	if (ms_total == 0)
+		ms_total = 1;
+
+	ms_remaining = ms_total;
+
+	/* Since Sleep() can sleep for less than the requested time, add a loop to
+	   ensure we only return after the requested length of time has elapsed */
+	do {
+		fio_gettime(&tv, NULL);
+		Sleep(ms_remaining);
+		ms_remaining = ms_total - mtime_since_now(&tv);
+	} while (ms_remaining > 0 && ms_remaining < ms_total);
+
+	/* this implementation will never sleep for less than the requested time */
+	if (rmtp != NULL) {
+		rmtp->tv_sec = 0;
+		rmtp->tv_nsec = 0;
+	}
+
+	return 0;
 }
 
 DIR *opendir(const char *dirname)
diff --git a/smalloc.c b/smalloc.c
index 5ba2004..d0b6f1e 100644
--- a/smalloc.c
+++ b/smalloc.c
@@ -206,7 +206,7 @@
 	pool->map = ptr;
 	pool->bitmap = (void *) ptr + (pool->nr_blocks * SMALLOC_BPL);
 
-	pool->lock = fio_mutex_init(1);
+	pool->lock = fio_mutex_init(FIO_MUTEX_UNLOCKED);
 	if (!pool->lock)
 		goto out_fail;