#include <sys/stat.h>
#include <sys/wait.h>
#include <math.h>
+#include <pthread.h>
#include "fio.h"
#include "smalloc.h"
int shm_id = 0;
int temp_stall_ts;
unsigned long done_secs = 0;
+pthread_mutex_t overlap_check = PTHREAD_MUTEX_INITIALIZER;
#define JOB_START_TIMEOUT (5 * 1000)
{
int r;
+ if (td->error)
+ return;
+
/*
* get immediately available events, if any
*/
io_u->ddir = DDIR_SYNC;
io_u->file = f;
+ io_u_set(td, io_u, IO_U_F_NO_FILE_PUT);
if (td_io_prep(td, io_u)) {
put_io_u(td, io_u);
static int fio_file_fsync(struct thread_data *td, struct fio_file *f)
{
- int ret;
+ int ret, ret2;
if (fio_file_open(f))
return fio_io_sync(td, f);
return 1;
ret = fio_io_sync(td, f);
- td_io_close_file(td, f);
- return ret;
+ ret2 = 0;
+ if (fio_file_open(f))
+ ret2 = td_io_close_file(td, f);
+ return (ret || ret2);
}
static inline void __update_ts_cache(struct thread_data *td)
/*
* Check if io_u will overlap an in-flight IO in the queue
*/
-static bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u)
+bool in_flight_overlap(struct io_u_queue *q, struct io_u *io_u)
{
bool overlap;
struct io_u *check_io_u;
td->error = 0;
}
- if (should_fsync(td) && td->o.end_fsync) {
+ if (should_fsync(td) && (td->o.end_fsync || td->o.fsync_on_close)) {
td_set_runstate(td, TD_FSYNCING);
for_each_file(td, f, i) {
if (td->io_ops->io_u_free)
td->io_ops->io_u_free(td, io_u);
- fio_memfree(io_u, sizeof(*io_u));
+ fio_memfree(io_u, sizeof(*io_u), td_offload_overlap(td));
}
free_io_mem(td);
io_u_rexit(&td->io_u_requeues);
- io_u_qexit(&td->io_u_freelist);
- io_u_qexit(&td->io_u_all);
+ io_u_qexit(&td->io_u_freelist, false);
+ io_u_qexit(&td->io_u_all, td_offload_overlap(td));
free_file_completion_logging(td);
}
err = 0;
err += !io_u_rinit(&td->io_u_requeues, td->o.iodepth);
- err += !io_u_qinit(&td->io_u_freelist, td->o.iodepth);
- err += !io_u_qinit(&td->io_u_all, td->o.iodepth);
+ err += !io_u_qinit(&td->io_u_freelist, td->o.iodepth, false);
+ err += !io_u_qinit(&td->io_u_all, td->o.iodepth, td_offload_overlap(td));
if (err) {
log_err("fio: failed setting up IO queues\n");
if (td->terminate)
return 1;
- ptr = fio_memalign(cl_align, sizeof(*io_u));
+ ptr = fio_memalign(cl_align, sizeof(*io_u), td_offload_overlap(td));
if (!ptr) {
log_err("fio: unable to allocate aligned memory\n");
- break;
+ return 1;
}
io_u = ptr;
static int exec_string(struct thread_options *o, const char *string, const char *mode)
{
- size_t newlen = strlen(string) + strlen(o->name) + strlen(mode) + 9 + 1;
+ size_t newlen = strlen(string) + strlen(o->name) + strlen(mode) + 13 + 1;
int ret;
char *str;
str = malloc(newlen);
- sprintf(str, "%s &> %s.%s.txt", string, o->name, mode);
+ sprintf(str, "%s > %s.%s.txt 2>&1", string, o->name, mode);
log_info("%s : Saving output of %s in %s.%s.txt\n",o->name, mode, o->name, mode);
ret = system(str);
struct sk_out *sk_out = fd->sk_out;
uint64_t bytes_done[DDIR_RWDIR_CNT];
int deadlock_loop_cnt;
- bool clear_state, did_some_io;
+ bool clear_state;
int ret;
sk_out_assign(sk_out);
if (!init_iolog(td))
goto err;
+ if (td_io_init(td))
+ goto err;
+
if (init_io_u(td))
goto err;
+ if (td->io_ops->post_init && td->io_ops->post_init(td))
+ goto err;
+
if (o->verify_async && verify_async_init(td))
goto err;
if (!o->create_serialize && setup_files(td))
goto err;
- if (td_io_init(td))
- goto err;
-
if (!init_random_map(td))
goto err;
memset(bytes_done, 0, sizeof(bytes_done));
clear_state = false;
- did_some_io = false;
while (keep_running(td)) {
uint64_t verify_bytes;
td_ioengine_flagged(td, FIO_UNIDIR))
continue;
- if (ddir_rw_sum(bytes_done))
- did_some_io = true;
-
clear_io_state(td, 0);
fio_gettime(&td->start, NULL);
}
/*
- * If td ended up with no I/O when it should have had,
- * then something went wrong unless FIO_NOIO or FIO_DISKLESSIO.
- * (Are we not missing other flags that can be ignored ?)
+ * Acquire this lock if we were doing overlap checking in
+ * offload mode so that we don't clean up this job while
+ * another thread is checking its io_u's for overlap
*/
- if ((td->o.size || td->o.io_size) && !ddir_rw_sum(bytes_done) &&
- !did_some_io && !td->o.create_only &&
- !(td_ioengine_flagged(td, FIO_NOIO) ||
- td_ioengine_flagged(td, FIO_DISKLESSIO)))
- log_err("%s: No I/O performed by %s, "
- "perhaps try --debug=io option for details?\n",
- td->o.name, td->io_ops->name);
-
+ if (td_offload_overlap(td))
+ pthread_mutex_lock(&overlap_check);
td_set_runstate(td, TD_FINISHING);
+ if (td_offload_overlap(td))
+ pthread_mutex_unlock(&overlap_check);
update_rusage_stat(td);
td->ts.total_run_time = mtime_since_now(&td->epoch);