[PATCH] Add support for the read/write interface of SG v3
diff --git a/fio-io.c b/fio-io.c
index dee02ab..b688fa2 100644
--- a/fio-io.c
+++ b/fio-io.c
@@ -481,6 +481,24 @@
}
}
+static int fio_sgio_doio(struct thread_data *td, struct sg_io_hdr *hdr)
+{
+ int ret;
+
+ if (td->filetype == FIO_TYPE_BD)
+ return ioctl(td->fd, SG_IO, &hdr);
+
+ ret = write(td->fd, hdr, sizeof(*hdr));
+ if (ret < 0)
+ return errno;
+
+ ret = read(td->fd, hdr, sizeof(*hdr));
+ if (ret < 0)
+ return errno;
+
+ return 0;
+}
+
static int fio_sgio_sync(struct thread_data *td)
{
struct sgio_data *sd = td->io_data;
@@ -491,7 +509,7 @@
hdr.cmdp[0] = 0x35;
- return ioctl(td->fd, SG_IO, &hdr);
+ return fio_sgio_doio(td, &hdr);
}
static int fio_sgio_prep(struct thread_data *td, struct io_u *io_u)
@@ -532,7 +550,8 @@
struct sgio_data *sd = td->io_data;
int ret;
- ret = ioctl(td->fd, SG_IO, hdr);
+ ret = fio_sgio_doio(td, hdr);
+
if (ret < 0)
io_u->error = errno;
else if (hdr->status) {
@@ -555,22 +574,60 @@
return sd->last_io_u;
}
+static int fio_sgio_get_bs(struct thread_data *td, unsigned int *bs)
+{
+ struct sgio_data *sd = td->io_data;
+ struct sg_io_hdr hdr;
+ unsigned char buf[8];
+ int ret;
+
+ sgio_hdr_init(sd, &hdr, NULL);
+ memset(buf, 0, sizeof(buf));
+
+ hdr.cmdp[0] = 0x25;
+ hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ hdr.dxferp = buf;
+ hdr.dxfer_len = sizeof(buf);
+
+ ret = fio_sgio_doio(td, &hdr);
+ if (ret)
+ return ret;
+
+ *bs = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
+ return 0;
+}
+
int fio_sgio_init(struct thread_data *td)
{
struct sgio_data *sd;
- int bs;
+ unsigned int bs;
+ int ret;
- if (td->filetype != FIO_TYPE_BD) {
+ sd = malloc(sizeof(*sd));
+ sd->last_io_u = NULL;
+ td->io_data = sd;
+
+ 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 {
fprintf(stderr, "ioengine sgio only works on block devices\n");
return 1;
}
- if (ioctl(td->fd, BLKSSZGET, &bs) < 0) {
- td_verror(td, errno);
- return 1;
- }
-
- sd = malloc(sizeof(*sd));
sd->bs = bs;
td->io_prep = fio_sgio_prep;
@@ -585,9 +642,6 @@
* we want to do it, regardless of whether odirect is set or not
*/
td->override_sync = 1;
-
- sd->last_io_u = NULL;
- td->io_data = sd;
return 0;
}