int *fd_flags;
void *sgbuf;
unsigned int bs;
+ int type_checked;
};
static void sgio_hdr_init(struct sgio_data *sd, struct sg_io_hdr *hdr,
*/
struct fio_file *f = &td->files[0];
struct sgio_data *sd = td->io_ops->data;
- int left = max, ret, events, i, r = 0;
+ int left = max, ret, r = 0;
void *buf = sd->sgbuf;
+ unsigned int i, events;
/*
* Fill in the file descriptors
ret = poll(sd->pfds, td->nr_files, -1);
if (ret < 0) {
- td_verror(td, errno);
if (!r)
- r = -1;
+ r = -errno;
+ td_verror(td, errno, "poll");
break;
} else if (!ret)
continue;
if (ret < 0) {
if (errno == EAGAIN)
continue;
- td_verror(td, errno);
- r = -1;
+ r = -errno;
+ td_verror(td, errno, "read");
break;
} else if (ret) {
p += ret;
ret = ioctl(f->fd, SG_IO, hdr);
if (ret < 0)
- return ret;
+ return -errno;
return FIO_Q_COMPLETED;
}
if (sync) {
ret = read(f->fd, hdr, sizeof(*hdr));
if (ret < 0)
- return errno;
+ return -errno;
return FIO_Q_COMPLETED;
}
{
struct fio_file *f = io_u->file;
- if (td->filetype == FIO_TYPE_BD)
+ if (f->filetype == FIO_TYPE_BD)
return fio_sgio_ioctl_doio(td, f, io_u);
return fio_sgio_rw_doio(f, io_u, sync);
}
if (io_u->error) {
- td_verror(td, io_u->error);
+ td_verror(td, io_u->error, "xfer");
return FIO_Q_COMPLETED;
}
static int fio_sgio_init(struct thread_data *td)
{
- struct fio_file *f = &td->files[0];
struct sgio_data *sd;
- unsigned int bs;
- int ret;
sd = malloc(sizeof(*sd));
memset(sd, 0, sizeof(*sd));
td->io_ops->data = sd;
- if (td->filetype == FIO_TYPE_BD) {
+ /*
+ * we want to do it, regardless of whether odirect is set or not
+ */
+ td->override_sync = 1;
+ return 0;
+}
+
+static int fio_sgio_type_check(struct thread_data *td, struct fio_file *f)
+{
+ struct sgio_data *sd = td->io_ops->data;
+ unsigned int bs;
+
+ if (f->filetype == FIO_TYPE_BD) {
if (ioctl(f->fd, BLKSSZGET, &bs) < 0) {
- td_verror(td, errno);
- goto err;
+ td_verror(td, errno, "ioctl");
+ return 1;
}
- } else if (td->filetype == FIO_TYPE_CHAR) {
- int version;
+ } else if (f->filetype == FIO_TYPE_CHAR) {
+ int version, ret;
if (ioctl(f->fd, SG_GET_VERSION_NUM, &version) < 0) {
- td_verror(td, errno);
- goto err;
+ td_verror(td, errno, "ioctl");
+ return 1;
}
ret = fio_sgio_get_bs(td, &bs);
if (ret)
- goto err;
+ return 1;
} else {
log_err("ioengine sgio only works on block devices\n");
- goto err;
+ return 1;
}
sd->bs = bs;
- if (td->filetype == FIO_TYPE_BD) {
+ if (f->filetype == FIO_TYPE_BD) {
td->io_ops->getevents = NULL;
td->io_ops->event = NULL;
}
- /*
- * we want to do it, regardless of whether odirect is set or not
- */
- td->override_sync = 1;
return 0;
-err:
- free(sd->events);
- free(sd->cmds);
- free(sd->fd_flags);
- free(sd->pfds);
- free(sd->sgbuf);
- free(sd);
- td->io_ops->data = NULL;
- return 1;
+}
+
+static int fio_sgio_open(struct thread_data *td, struct fio_file *f)
+{
+ struct sgio_data *sd = td->io_ops->data;
+ int ret;
+
+ ret = generic_open_file(td, f);
+ if (ret)
+ return ret;
+
+ if (!sd->type_checked && fio_sgio_type_check(td, f)) {
+ generic_close_file(td, f);
+ return 1;
+ }
+
+ return 0;
}
static struct ioengine_ops ioengine = {
.getevents = fio_sgio_getevents,
.event = fio_sgio_event,
.cleanup = fio_sgio_cleanup,
+ .open_file = fio_sgio_open,
+ .close_file = generic_close_file,
.flags = FIO_SYNCIO | FIO_RAWIO,
};