FIO_URING_CMD_WMODE_VERIFY,
};
+enum uring_cmd_verify_mode {
+ FIO_URING_CMD_VMODE_READ = 1,
+ FIO_URING_CMD_VMODE_COMPARE,
+};
+
struct io_sq_ring {
unsigned *head;
unsigned *tail;
unsigned int readfua;
unsigned int writefua;
unsigned int write_mode;
+ unsigned int verify_mode;
struct cmdprio_options cmdprio_options;
unsigned int fixedbufs;
unsigned int registerfiles;
.category = FIO_OPT_C_ENGINE,
.group = FIO_OPT_G_IOURING,
},
+ {
+ .name = "verify_mode",
+ .lname = "Do verify based on the configured command (e.g., Read or Compare command)",
+ .type = FIO_OPT_STR,
+ .off1 = offsetof(struct ioring_options, verify_mode),
+ .help = "Issue Read or Compare command in the verification phase",
+ .def = "read",
+ .posval = {
+ { .ival = "read",
+ .oval = FIO_URING_CMD_VMODE_READ,
+ .help = "Issue Read commands in the verification phase"
+ },
+ { .ival = "compare",
+ .oval = FIO_URING_CMD_VMODE_COMPARE,
+ .help = "Issue Compare commands in the verification phase"
+ },
+ },
+ .category = FIO_OPT_C_ENGINE,
+ .group = FIO_OPT_G_IOURING,
+ },
{
.name = "fixedbufs",
.lname = "Fixed (pre-mapped) IO buffers",
struct nvme_dsm *dsm;
void *ptr = ld->dsm;
unsigned int dsm_size;
+ uint8_t read_opcode = nvme_cmd_read;
/* only supports nvme_uring_cmd */
if (o->cmd_type != FIO_URING_CMD_NVME)
ptr += io_u->index * dsm_size;
dsm = (struct nvme_dsm *)ptr;
+ /*
+ * If READ command belongs to the verification phase and the
+ * verify_mode=compare, convert READ to COMPARE command.
+ */
+ if (io_u->flags & IO_U_F_VER_LIST && io_u->ddir == DDIR_READ &&
+ o->verify_mode == FIO_URING_CMD_VMODE_COMPARE) {
+ populate_verify_io_u(td, io_u);
+ read_opcode = nvme_cmd_compare;
+ io_u_set(td, io_u, IO_U_F_VER_IN_DEV);
+ }
+
return fio_nvme_uring_cmd_prep(cmd, io_u,
o->nonvectored ? NULL : &ld->iovecs[io_u->index],
- dsm, ld->write_opcode, ld->cdw12_flags[io_u->ddir]);
+ dsm, read_opcode, ld->write_opcode,
+ ld->cdw12_flags[io_u->ddir]);
}
static struct io_u *fio_ioring_event(struct thread_data *td, int event)
int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
struct iovec *iov, struct nvme_dsm *dsm,
- uint8_t write_opcode, unsigned int cdw12_flags)
+ uint8_t read_opcode, uint8_t write_opcode,
+ unsigned int cdw12_flags)
{
struct nvme_data *data = FILE_ENG_DATA(io_u->file);
__u64 slba;
switch (io_u->ddir) {
case DDIR_READ:
- cmd->opcode = nvme_cmd_read;
+ cmd->opcode = read_opcode;
break;
case DDIR_WRITE:
cmd->opcode = write_opcode;
nvme_cmd_write = 0x01,
nvme_cmd_read = 0x02,
nvme_cmd_write_uncor = 0x04,
+ nvme_cmd_compare = 0x05,
nvme_cmd_write_zeroes = 0x08,
nvme_cmd_dsm = 0x09,
nvme_cmd_verify = 0x0c,
int fio_nvme_uring_cmd_prep(struct nvme_uring_cmd *cmd, struct io_u *io_u,
struct iovec *iov, struct nvme_dsm *dsm,
- uint8_t write_opcode, unsigned int cdw12_flags);
+ uint8_t read_opcode, uint8_t write_opcode,
+ unsigned int cdw12_flags);
void fio_nvme_pi_fill(struct nvme_uring_cmd *cmd, struct io_u *io_u,
struct nvme_cmd_ext_io_opts *opts);