- if (td->filetype == FIO_TYPE_BD) {
- if (ioctl(td->fd, BLKSSZGET, &bs) < 0) {
- td_verror(td, errno);
- return 1;
- }
- } else if (td->filetype == FIO_TYPE_CHAR) {
- int version;
-
- if (ioctl(td->fd, SG_GET_VERSION_NUM, &version) < 0) {
- td_verror(td, errno);
- return 1;
- }
-
- ret = fio_sgio_get_bs(td, &bs);
- if (ret)
- return ret;
- } else {
- log_err("ioengine sgio only works on block devices\n");
- return 1;
- }
-
- sd->bs = bs;
-
- td->io_prep = fio_sgio_prep;
- td->io_queue = fio_sgio_queue;
-
- if (td->filetype == FIO_TYPE_BD)
- td->io_getevents = fio_syncio_getevents;
- else
- td->io_getevents = fio_sgio_getevents;
-
- td->io_event = fio_sgio_event;
- td->io_cancel = NULL;
- td->io_cleanup = fio_syncio_cleanup;
- td->io_sync = fio_sgio_sync;
-
- /*
- * we want to do it, regardless of whether odirect is set or not
- */
- td->override_sync = 1;
- return 0;
-}
-
-#else /* FIO_HAVE_SGIO */
-
-int fio_sgio_init(struct thread_data *td)
-{
- return EINVAL;
-}
-
-#endif /* FIO_HAVE_SGIO */
-
-#ifdef FIO_HAVE_SPLICE
-struct spliceio_data {
- struct io_u *last_io_u;
- int pipe[2];
-};
-
-static struct io_u *fio_spliceio_event(struct thread_data *td, int event)
-{
- struct spliceio_data *sd = td->io_data;
-
- assert(event == 0);
-
- return sd->last_io_u;
-}
-
-/*
- * For splice reading, we unfortunately cannot (yet) vmsplice the other way.
- * So just splice the data from the file into the pipe, and use regular
- * read to fill the buffer. Doesn't make a lot of sense, but...
- */
-static int fio_splice_read(struct thread_data *td, struct io_u *io_u)
-{
- struct spliceio_data *sd = td->io_data;
- int ret, ret2, buflen;
- off_t offset;
- void *p;
-
- offset = io_u->offset;
- buflen = io_u->buflen;
- p = io_u->buf;
- while (buflen) {
- int this_len = buflen;
-
- if (this_len > SPLICE_DEF_SIZE)
- this_len = SPLICE_DEF_SIZE;
-
- ret = splice(td->fd, &offset, sd->pipe[1], NULL, this_len, SPLICE_F_MORE);
- if (ret < 0) {
- if (errno == ENODATA || errno == EAGAIN)
- continue;
-
- return errno;
- }
-
- buflen -= ret;