X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Ffio-engine-sg.c;h=2762e0bac3b25783f02ccdf6366327eb42d98583;hp=01eba8d58391ebe957f4213452946a5cef09bf93;hb=cb781c758e5df7ff4c6f655c1e4f9df3043a4be9;hpb=7313b48c3196b4750f4103e8622126039e2231c6 diff --git a/engines/fio-engine-sg.c b/engines/fio-engine-sg.c index 01eba8d5..2762e0ba 100644 --- a/engines/fio-engine-sg.c +++ b/engines/fio-engine-sg.c @@ -11,6 +11,8 @@ #include "fio.h" #include "os.h" +#ifdef FIO_HAVE_SGIO + struct sgio_cmd { unsigned char cdb[10]; int nr; @@ -151,28 +153,6 @@ static int fio_sgio_doio(struct thread_data *td, struct io_u *io_u, int sync) return fio_sgio_rw_doio(f, io_u, sync); } -static int fio_sgio_sync(struct thread_data *td, struct fio_file fio_unused *f) -{ - struct sgio_data *sd = td->io_ops->data; - struct sg_io_hdr *hdr; - struct io_u *io_u; - int ret; - - io_u = __get_io_u(td); - if (!io_u) - return ENOMEM; - - hdr = &io_u->hdr; - sgio_hdr_init(sd, hdr, io_u, 0); - hdr->dxfer_direction = SG_DXFER_NONE; - - hdr->cmdp[0] = 0x35; - - ret = fio_sgio_doio(td, io_u, 1); - put_io_u(td, io_u); - return ret; -} - static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) { struct sg_io_hdr *hdr = &io_u->hdr; @@ -184,24 +164,34 @@ static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) return EINVAL; } - sgio_hdr_init(sd, hdr, io_u, 1); - if (io_u->ddir == DDIR_READ) { + sgio_hdr_init(sd, hdr, io_u, 1); + hdr->dxfer_direction = SG_DXFER_FROM_DEV; hdr->cmdp[0] = 0x28; - } else { + } else if (io_u->ddir == DDIR_WRITE) { + sgio_hdr_init(sd, hdr, io_u, 1); + hdr->dxfer_direction = SG_DXFER_TO_DEV; hdr->cmdp[0] = 0x2a; + } else { + sgio_hdr_init(sd, hdr, io_u, 0); + + hdr->dxfer_direction = SG_DXFER_NONE; + hdr->cmdp[0] = 0x35; + } + + if (hdr->dxfer_direction != SG_DXFER_NONE) { + nr_blocks = io_u->buflen / sd->bs; + lba = io_u->offset / sd->bs; + hdr->cmdp[2] = (lba >> 24) & 0xff; + hdr->cmdp[3] = (lba >> 16) & 0xff; + hdr->cmdp[4] = (lba >> 8) & 0xff; + hdr->cmdp[5] = lba & 0xff; + hdr->cmdp[7] = (nr_blocks >> 8) & 0xff; + hdr->cmdp[8] = nr_blocks & 0xff; } - nr_blocks = io_u->buflen / sd->bs; - lba = io_u->offset / sd->bs; - hdr->cmdp[2] = (lba >> 24) & 0xff; - hdr->cmdp[3] = (lba >> 16) & 0xff; - hdr->cmdp[4] = (lba >> 8) & 0xff; - hdr->cmdp[5] = lba & 0xff; - hdr->cmdp[7] = (nr_blocks >> 8) & 0xff; - hdr->cmdp[8] = nr_blocks & 0xff; return 0; } @@ -210,7 +200,7 @@ static int fio_sgio_queue(struct thread_data *td, struct io_u *io_u) struct sg_io_hdr *hdr = &io_u->hdr; int ret; - ret = fio_sgio_doio(td, io_u, 0); + ret = fio_sgio_doio(td, io_u, io_u->ddir == DDIR_SYNC); if (ret < 0) io_u->error = errno; @@ -276,29 +266,32 @@ static int fio_sgio_init(struct thread_data *td) int ret; sd = malloc(sizeof(*sd)); + memset(sd, 0, sizeof(*sd)); sd->cmds = malloc(td->iodepth * sizeof(struct sgio_cmd)); + memset(sd->cmds, 0, td->iodepth * sizeof(struct sgio_cmd)); sd->events = malloc(td->iodepth * sizeof(struct io_u *)); + memset(sd->events, 0, td->iodepth * sizeof(struct io_u *)); td->io_ops->data = sd; if (td->filetype == FIO_TYPE_BD) { if (ioctl(f->fd, BLKSSZGET, &bs) < 0) { td_verror(td, errno); - return 1; + goto err; } } else if (td->filetype == FIO_TYPE_CHAR) { int version; if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) { td_verror(td, errno); - return 1; + goto err; } ret = fio_sgio_get_bs(td, &bs); if (ret) - return ret; + goto err; } else { log_err("ioengine sgio only works on block devices\n"); - return 1; + goto err; } sd->bs = bs; @@ -313,6 +306,11 @@ static int fio_sgio_init(struct thread_data *td) */ td->override_sync = 1; return 0; +err: + free(sd->events); + free(sd->cmds); + free(sd); + return 1; } struct ioengine_ops ioengine = { @@ -324,6 +322,26 @@ struct ioengine_ops ioengine = { .getevents = fio_sgio_getevents, .event = fio_sgio_event, .cleanup = fio_sgio_cleanup, - .sync = fio_sgio_sync, .flags = FIO_SYNCIO | FIO_RAWIO, }; + +#else /* FIO_HAVE_SGIO */ + +/* + * When we have a proper configure system in place, we simply wont build + * and install this io engine. For now install a crippled version that + * just complains and fails to load. + */ +static int fio_sgio_init(struct thread_data fio_unused *td) +{ + fprintf(stderr, "fio: sgio not available\n"); + return 1; +} + +struct ioengine_ops ioengine = { + .name = "sgio", + .version = FIO_IOOPS_VERSION, + .init = fio_sgio_init, +}; + +#endif