X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Ffio-engine-sg.c;h=9c5037f5d11fb0391cc25eda994a44366e3297ce;hp=0db5ca93ba48da4df51cdee77ec2409e855bf2ed;hb=5f350952eff89948bfbf1eb6ac4d3d08a9109581;hpb=53cdc6864f7471b28cc9b40a5314ab43e5b1cb5e diff --git a/engines/fio-engine-sg.c b/engines/fio-engine-sg.c index 0db5ca93..9c5037f5 100644 --- a/engines/fio-engine-sg.c +++ b/engines/fio-engine-sg.c @@ -8,8 +8,11 @@ #include #include #include -#include "fio.h" -#include "os.h" + +#include "../fio.h" +#include "../os.h" + +#ifdef FIO_HAVE_SGIO struct sgio_cmd { unsigned char cdb[10]; @@ -112,8 +115,8 @@ static int fio_sgio_getevents(struct thread_data *td, int min, int max, return r; } -static int fio_sgio_ioctl_doio(struct thread_data *td, struct fio_file *f, - struct io_u *io_u) +static int fio_sgio_ioctl_doio(struct thread_data *td, + struct fio_file *f, struct io_u *io_u) { struct sgio_data *sd = td->io_ops->data; struct sg_io_hdr *hdr = &io_u->hdr; @@ -123,8 +126,7 @@ static int fio_sgio_ioctl_doio(struct thread_data *td, struct fio_file *f, return ioctl(f->fd, SG_IO, hdr); } -static int fio_sgio_rw_doio(struct thread_data *td, struct fio_file *f, - struct io_u *io_u, int sync) +static int fio_sgio_rw_doio(struct fio_file *f, struct io_u *io_u, int sync) { struct sg_io_hdr *hdr = &io_u->hdr; int ret; @@ -149,29 +151,7 @@ static int fio_sgio_doio(struct thread_data *td, struct io_u *io_u, int sync) if (td->filetype == FIO_TYPE_BD) return fio_sgio_ioctl_doio(td, f, io_u); - return fio_sgio_rw_doio(td, f, io_u, sync); -} - -static int fio_sgio_sync(struct thread_data *td, struct fio_file *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; + return fio_sgio_rw_doio(f, io_u, sync); } static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u) @@ -185,24 +165,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; } @@ -211,7 +201,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; @@ -277,29 +267,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; @@ -314,9 +307,14 @@ 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 = { +static struct ioengine_ops ioengine = { .name = "sg", .version = FIO_IOOPS_VERSION, .init = fio_sgio_init, @@ -325,6 +323,36 @@ struct ioengine_ops ioengine = { .getevents = fio_sgio_getevents, .event = fio_sgio_event, .cleanup = fio_sgio_cleanup, - .sync = fio_sgio_sync, - .flags = FIO_SYNCIO, + .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; +} + +static struct ioengine_ops ioengine = { + .name = "sgio", + .version = FIO_IOOPS_VERSION, + .init = fio_sgio_init, }; + +#endif + +static void fio_init fio_sgio_register(void) +{ + register_ioengine(&ioengine); +} + +static void fio_exit fio_sgio_unregister(void) +{ + unregister_ioengine(&ioengine); +}