Revert "client: respect terse output on client <--> backend relationship"
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index c58dcf0493bb50347367f8a1d6886ded60ec7748..a3540d14714ef45f59f7fcf22744bae507f6b491 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -10,6 +10,7 @@
 #include "err.h"
 #include "lib/pow2.h"
 #include "minmax.h"
 #include "err.h"
 #include "lib/pow2.h"
 #include "minmax.h"
+#include "zbd.h"
 
 struct io_completion_data {
        int nr;                         /* input */
 
 struct io_completion_data {
        int nr;                         /* input */
@@ -31,21 +32,27 @@ static bool random_map_free(struct fio_file *f, const uint64_t block)
 /*
  * Mark a given offset as used in the map.
  */
 /*
  * Mark a given offset as used in the map.
  */
-static void mark_random_map(struct thread_data *td, struct io_u *io_u)
+static uint64_t mark_random_map(struct thread_data *td, struct io_u *io_u,
+                               uint64_t offset, uint64_t buflen)
 {
        unsigned long long min_bs = td->o.min_bs[io_u->ddir];
        struct fio_file *f = io_u->file;
        unsigned long long nr_blocks;
        uint64_t block;
 
 {
        unsigned long long min_bs = td->o.min_bs[io_u->ddir];
        struct fio_file *f = io_u->file;
        unsigned long long nr_blocks;
        uint64_t block;
 
-       block = (io_u->offset - f->file_offset) / (uint64_t) min_bs;
-       nr_blocks = (io_u->buflen + min_bs - 1) / min_bs;
+       block = (offset - f->file_offset) / (uint64_t) min_bs;
+       nr_blocks = (buflen + min_bs - 1) / min_bs;
+       assert(nr_blocks > 0);
 
 
-       if (!(io_u->flags & IO_U_F_BUSY_OK))
+       if (!(io_u->flags & IO_U_F_BUSY_OK)) {
                nr_blocks = axmap_set_nr(f->io_axmap, block, nr_blocks);
                nr_blocks = axmap_set_nr(f->io_axmap, block, nr_blocks);
+               assert(nr_blocks > 0);
+       }
+
+       if ((nr_blocks * min_bs) < buflen)
+               buflen = nr_blocks * min_bs;
 
 
-       if ((nr_blocks * min_bs) < io_u->buflen)
-               io_u->buflen = nr_blocks * min_bs;
+       return buflen;
 }
 
 static uint64_t last_block(struct thread_data *td, struct fio_file *f,
 }
 
 static uint64_t last_block(struct thread_data *td, struct fio_file *f,
@@ -64,7 +71,7 @@ static uint64_t last_block(struct thread_data *td, struct fio_file *f,
        if (max_size > f->real_file_size)
                max_size = f->real_file_size;
 
        if (max_size > f->real_file_size)
                max_size = f->real_file_size;
 
-       if (td->o.zone_range)
+       if (td->o.zone_mode == ZONE_MODE_STRIDED && td->o.zone_range)
                max_size = td->o.zone_range;
 
        if (td->o.min_bs[ddir] > td->o.ba[ddir])
                max_size = td->o.zone_range;
 
        if (td->o.min_bs[ddir] > td->o.ba[ddir])
@@ -761,10 +768,18 @@ void put_file_log(struct thread_data *td, struct fio_file *f)
 
 void put_io_u(struct thread_data *td, struct io_u *io_u)
 {
 
 void put_io_u(struct thread_data *td, struct io_u *io_u)
 {
+       const bool needs_lock = td_async_processing(td);
+
+       if (io_u->post_submit) {
+               io_u->post_submit(io_u, io_u->error == 0);
+               io_u->post_submit = NULL;
+       }
+
        if (td->parent)
                td = td->parent;
 
        if (td->parent)
                td = td->parent;
 
-       td_io_u_lock(td);
+       if (needs_lock)
+               __td_io_u_lock(td);
 
        if (io_u->file && !(io_u->flags & IO_U_F_NO_FILE_PUT))
                put_file_log(td, io_u->file);
 
        if (io_u->file && !(io_u->flags & IO_U_F_NO_FILE_PUT))
                put_file_log(td, io_u->file);
@@ -778,7 +793,9 @@ void put_io_u(struct thread_data *td, struct io_u *io_u)
        }
        io_u_qpush(&td->io_u_freelist, io_u);
        td_io_u_free_notify(td);
        }
        io_u_qpush(&td->io_u_freelist, io_u);
        td_io_u_free_notify(td);
-       td_io_u_unlock(td);
+
+       if (needs_lock)
+               __td_io_u_unlock(td);
 }
 
 void clear_io_u(struct thread_data *td, struct io_u *io_u)
 }
 
 void clear_io_u(struct thread_data *td, struct io_u *io_u)
@@ -789,6 +806,7 @@ void clear_io_u(struct thread_data *td, struct io_u *io_u)
 
 void requeue_io_u(struct thread_data *td, struct io_u **io_u)
 {
 
 void requeue_io_u(struct thread_data *td, struct io_u **io_u)
 {
+       const bool needs_lock = td_async_processing(td);
        struct io_u *__io_u = *io_u;
        enum fio_ddir ddir = acct_ddir(__io_u);
 
        struct io_u *__io_u = *io_u;
        enum fio_ddir ddir = acct_ddir(__io_u);
 
@@ -797,7 +815,8 @@ void requeue_io_u(struct thread_data *td, struct io_u **io_u)
        if (td->parent)
                td = td->parent;
 
        if (td->parent)
                td = td->parent;
 
-       td_io_u_lock(td);
+       if (needs_lock)
+               __td_io_u_lock(td);
 
        io_u_set(td, __io_u, IO_U_F_FREE);
        if ((__io_u->flags & IO_U_F_FLIGHT) && ddir_rw(ddir))
 
        io_u_set(td, __io_u, IO_U_F_FREE);
        if ((__io_u->flags & IO_U_F_FLIGHT) && ddir_rw(ddir))
@@ -811,14 +830,21 @@ void requeue_io_u(struct thread_data *td, struct io_u **io_u)
 
        io_u_rpush(&td->io_u_requeues, __io_u);
        td_io_u_free_notify(td);
 
        io_u_rpush(&td->io_u_requeues, __io_u);
        td_io_u_free_notify(td);
-       td_io_u_unlock(td);
+
+       if (needs_lock)
+               __td_io_u_unlock(td);
+
        *io_u = NULL;
 }
 
        *io_u = NULL;
 }
 
-static void __fill_io_u_zone(struct thread_data *td, struct io_u *io_u)
+static void setup_strided_zone_mode(struct thread_data *td, struct io_u *io_u)
 {
        struct fio_file *f = io_u->file;
 
 {
        struct fio_file *f = io_u->file;
 
+       assert(td->o.zone_mode == ZONE_MODE_STRIDED);
+       assert(td->o.zone_size);
+       assert(td->o.zone_range);
+
        /*
         * See if it's time to switch to a new zone
         */
        /*
         * See if it's time to switch to a new zone
         */
@@ -857,6 +883,8 @@ static void __fill_io_u_zone(struct thread_data *td, struct io_u *io_u)
 static int fill_io_u(struct thread_data *td, struct io_u *io_u)
 {
        bool is_random;
 static int fill_io_u(struct thread_data *td, struct io_u *io_u)
 {
        bool is_random;
+       uint64_t offset;
+       enum io_u_action ret;
 
        if (td_ioengine_flagged(td, FIO_NOIO))
                goto out;
 
        if (td_ioengine_flagged(td, FIO_NOIO))
                goto out;
@@ -869,11 +897,8 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
        if (!ddir_rw(io_u->ddir))
                goto out;
 
        if (!ddir_rw(io_u->ddir))
                goto out;
 
-       /*
-        * When file is zoned zone_range is always positive
-        */
-       if (td->o.zone_range)
-               __fill_io_u_zone(td, io_u);
+       if (td->o.zone_mode == ZONE_MODE_STRIDED)
+               setup_strided_zone_mode(td, io_u);
 
        /*
         * No log, let the seq/rand engine retrieve the next buflen and
 
        /*
         * No log, let the seq/rand engine retrieve the next buflen and
@@ -890,6 +915,13 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
                return 1;
        }
 
                return 1;
        }
 
+       offset = io_u->offset;
+       if (td->o.zone_mode == ZONE_MODE_ZBD) {
+               ret = zbd_adjust_block(td, io_u);
+               if (ret == io_u_eof)
+                       return 1;
+       }
+
        if (io_u->offset + io_u->buflen > io_u->file->real_file_size) {
                dprint(FD_IO, "io_u %p, off=0x%llx + len=0x%llx exceeds file size=0x%llx\n",
                        io_u,
        if (io_u->offset + io_u->buflen > io_u->file->real_file_size) {
                dprint(FD_IO, "io_u %p, off=0x%llx + len=0x%llx exceeds file size=0x%llx\n",
                        io_u,
@@ -902,7 +934,7 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
         * mark entry before potentially trimming io_u
         */
        if (td_random(td) && file_randommap(td, io_u->file))
         * mark entry before potentially trimming io_u
         */
        if (td_random(td) && file_randommap(td, io_u->file))
-               mark_random_map(td, io_u);
+               io_u->buflen = mark_random_map(td, io_u, offset, io_u->buflen);
 
 out:
        dprint_io_u(io_u, "fill");
 
 out:
        dprint_io_u(io_u, "fill");
@@ -1303,6 +1335,11 @@ static long set_io_u_file(struct thread_data *td, struct io_u *io_u)
                if (!fill_io_u(td, io_u))
                        break;
 
                if (!fill_io_u(td, io_u))
                        break;
 
+               if (io_u->post_submit) {
+                       io_u->post_submit(io_u, false);
+                       io_u->post_submit = NULL;
+               }
+
                put_file_log(td, f);
                td_io_close_file(td, f);
                io_u->file = NULL;
                put_file_log(td, f);
                td_io_close_file(td, f);
                io_u->file = NULL;
@@ -1477,13 +1514,15 @@ bool queue_full(const struct thread_data *td)
 
 struct io_u *__get_io_u(struct thread_data *td)
 {
 
 struct io_u *__get_io_u(struct thread_data *td)
 {
+       const bool needs_lock = td_async_processing(td);
        struct io_u *io_u = NULL;
        int ret;
 
        if (td->stop_io)
                return NULL;
 
        struct io_u *io_u = NULL;
        int ret;
 
        if (td->stop_io)
                return NULL;
 
-       td_io_u_lock(td);
+       if (needs_lock)
+               __td_io_u_lock(td);
 
 again:
        if (!io_u_rempty(&td->io_u_requeues))
 
 again:
        if (!io_u_rempty(&td->io_u_requeues))
@@ -1520,7 +1559,9 @@ again:
                goto again;
        }
 
                goto again;
        }
 
-       td_io_u_unlock(td);
+       if (needs_lock)
+               __td_io_u_unlock(td);
+
        return io_u;
 }
 
        return io_u;
 }