Add support for zoned block devices
[fio.git] / io_u.c
diff --git a/io_u.c b/io_u.c
index 29a360a95424a72cbf1c7f0c0b753efdbcf06f18..3fbcf0fdd5bba1cffc94cf4a96e092558bc52f44 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 "zbd.h"
 
 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.
  */
-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;
 
-       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);
+               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,
@@ -866,6 +873,8 @@ static void setup_strided_zone_mode(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;
+       uint64_t offset;
+       enum io_u_action ret;
 
        if (td_ioengine_flagged(td, FIO_NOIO))
                goto out;
@@ -896,6 +905,13 @@ static int fill_io_u(struct thread_data *td, struct io_u *io_u)
                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,
@@ -908,7 +924,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_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");