client: use temp buffer for single output flush for json/disk util
[fio.git] / ioengines.c
index 965581aa4157c8594fbc20735a8ac36f438d24b7..ba02952b1f0f8d0c8ae9bebe31e091a0302046aa 100644 (file)
@@ -9,7 +9,6 @@
  * generic io engine that could be used for other projects.
  *
  */
-#include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
@@ -19,6 +18,7 @@
 
 #include "fio.h"
 #include "diskutil.h"
+#include "zbd.h"
 
 static FLIST_HEAD(engine_list);
 
@@ -277,11 +277,11 @@ out:
        return r;
 }
 
-int td_io_queue(struct thread_data *td, struct io_u *io_u)
+enum fio_q_status td_io_queue(struct thread_data *td, struct io_u *io_u)
 {
        const enum fio_ddir ddir = acct_ddir(io_u);
-       unsigned long buflen = io_u->xfer_buflen;
-       int ret;
+       unsigned long long buflen = io_u->xfer_buflen;
+       enum fio_q_status ret;
 
        dprint_io_u(io_u, "queue");
        fio_ro_check(td, io_u);
@@ -320,6 +320,10 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
        }
 
        ret = td->io_ops->queue(td, io_u);
+       if (ret != FIO_Q_BUSY && io_u->post_submit) {
+               io_u->post_submit(io_u, io_u->error == 0);
+               io_u->post_submit = NULL;
+       }
 
        unlock_file(td, io_u->file);
 
@@ -351,7 +355,14 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
                         "invalid block size. Try setting direct=0.\n");
        }
 
-       if (!td->io_ops->commit || io_u->ddir == DDIR_TRIM) {
+       if (zbd_unaligned_write(io_u->error) &&
+           td->io_issues[io_u->ddir & 1] == 1 &&
+           td->o.zone_mode != ZONE_MODE_ZBD) {
+               log_info("fio: first I/O failed. If %s is a zoned block device, consider --zonemode=zbd\n",
+                        io_u->file->file_name);
+       }
+
+       if (!td->io_ops->commit) {
                io_u_mark_submit(td, 1);
                io_u_mark_complete(td, 1);
        }
@@ -362,18 +373,13 @@ int td_io_queue(struct thread_data *td, struct io_u *io_u)
                        td->ts.total_io_u[io_u->ddir]++;
                }
        } else if (ret == FIO_Q_QUEUED) {
-               int r;
-
                td->io_u_queued++;
 
                if (ddir_rw(io_u->ddir) || ddir_sync(io_u->ddir))
                        td->ts.total_io_u[io_u->ddir]++;
 
-               if (td->io_u_queued >= td->o.iodepth_batch) {
-                       r = td_io_commit(td);
-                       if (r < 0)
-                               return r;
-               }
+               if (td->io_u_queued >= td->o.iodepth_batch)
+                       td_io_commit(td);
        }
 
        if (!td_ioengine_flagged(td, FIO_SYNCIO)) {
@@ -411,14 +417,14 @@ int td_io_init(struct thread_data *td)
        return ret;
 }
 
-int td_io_commit(struct thread_data *td)
+void td_io_commit(struct thread_data *td)
 {
        int ret;
 
        dprint(FD_IO, "calling ->commit(), depth %d\n", td->cur_depth);
 
        if (!td->cur_depth || !td->io_u_queued)
-               return 0;
+               return;
 
        io_u_mark_depth(td, td->io_u_queued);
 
@@ -433,12 +439,18 @@ int td_io_commit(struct thread_data *td)
         */
        td->io_u_in_flight += td->io_u_queued;
        td->io_u_queued = 0;
-
-       return 0;
 }
 
 int td_io_open_file(struct thread_data *td, struct fio_file *f)
 {
+       if (fio_file_closing(f)) {
+               /*
+                * Open translates to undo closing.
+                */
+               fio_file_clear_closing(f);
+               get_file(f);
+               return 0;
+       }
        assert(!fio_file_open(f));
        assert(f->fd == -1);
        assert(td->io_ops->open_file);
@@ -548,11 +560,6 @@ int td_io_close_file(struct thread_data *td, struct fio_file *f)
         */
        fio_file_set_closing(f);
 
-       disk_util_dec(f->du);
-
-       if (td->o.file_lock_mode != FILE_LOCK_NONE)
-               unlock_file_all(td, f);
-
        return put_file(td, f);
 }
 
@@ -582,6 +589,7 @@ int td_io_get_file_size(struct thread_data *td, struct fio_file *f)
 int fio_show_ioengine_help(const char *engine)
 {
        struct flist_head *entry;
+       struct thread_data td;
        struct ioengine_ops *io_ops;
        char *sep;
        int ret = 1;
@@ -600,7 +608,10 @@ int fio_show_ioengine_help(const char *engine)
                sep++;
        }
 
-       io_ops = __load_ioengine(engine);
+       memset(&td, 0, sizeof(struct thread_data));
+       td.o.ioengine = (char *)engine;
+       io_ops = load_ioengine(&td);
+
        if (!io_ops) {
                log_info("IO engine %s not found\n", engine);
                return 1;
@@ -611,5 +622,6 @@ int fio_show_ioengine_help(const char *engine)
        else
                log_info("IO engine %s has no options\n", io_ops->name);
 
+       free_ioengine(&td);
        return ret;
 }