summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bhyve/block_if.c7
-rw-r--r--usr.sbin/bhyve/pci_virtio_block.c26
2 files changed, 24 insertions, 9 deletions
diff --git a/usr.sbin/bhyve/block_if.c b/usr.sbin/bhyve/block_if.c
index 5934006..e765987 100644
--- a/usr.sbin/bhyve/block_if.c
+++ b/usr.sbin/bhyve/block_if.c
@@ -80,6 +80,7 @@ struct blockif_elem {
struct blockif_ctxt {
int bc_magic;
int bc_fd;
+ int bc_ischr;
int bc_rdonly;
off_t bc_size;
int bc_sectsz;
@@ -190,6 +191,11 @@ blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be)
err = errno;
break;
case BOP_FLUSH:
+ if (bc->bc_ischr) {
+ if (ioctl(bc->bc_fd, DIOCGFLUSH))
+ err = errno;
+ } else if (fsync(bc->bc_fd))
+ err = errno;
break;
default:
err = EINVAL;
@@ -348,6 +354,7 @@ blockif_open(const char *optstr, const char *ident)
bc->bc_magic = BLOCKIF_SIG;
bc->bc_fd = fd;
+ bc->bc_ischr = S_ISCHR(sbuf.st_mode);
bc->bc_rdonly = ro;
bc->bc_size = size;
bc->bc_sectsz = sectsz;
diff --git a/usr.sbin/bhyve/pci_virtio_block.c b/usr.sbin/bhyve/pci_virtio_block.c
index 4172319..fef7fec 100644
--- a/usr.sbin/bhyve/pci_virtio_block.c
+++ b/usr.sbin/bhyve/pci_virtio_block.c
@@ -128,6 +128,7 @@ struct pci_vtblk_softc {
pthread_mutex_t vsc_mtx;
struct vqueue_info vbsc_vq;
int vbsc_fd;
+ int vbsc_ischr;
struct vtblk_config vbsc_cfg;
char vbsc_ident[VTBLK_BLK_ID_BYTES];
};
@@ -216,12 +217,15 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq)
DPRINTF(("virtio-block: %s op, %d bytes, %d segs, offset %ld\n\r",
writeop ? "write" : "read/ident", iolen, i - 1, offset));
+ err = 0;
switch (type) {
case VBH_OP_WRITE:
- err = pwritev(sc->vbsc_fd, iov + 1, i - 1, offset);
+ if (pwritev(sc->vbsc_fd, iov + 1, i - 1, offset) < 0)
+ err = errno;
break;
case VBH_OP_READ:
- err = preadv(sc->vbsc_fd, iov + 1, i - 1, offset);
+ if (preadv(sc->vbsc_fd, iov + 1, i - 1, offset) < 0)
+ err = errno;
break;
case VBH_OP_IDENT:
/* Assume a single buffer */
@@ -231,7 +235,11 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq)
break;
case VBH_OP_FLUSH:
case VBH_OP_FLUSH_OUT:
- err = fsync(sc->vbsc_fd);
+ if (sc->vbsc_ischr) {
+ if (ioctl(sc->vbsc_fd, DIOCGFLUSH))
+ err = errno;
+ } else if (fsync(sc->vbsc_fd))
+ err = errno;
break;
default:
err = -ENOSYS;
@@ -239,12 +247,11 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq)
}
/* convert errno into a virtio block error return */
- if (err < 0) {
- if (err == -ENOSYS)
- *status = VTBLK_S_UNSUPP;
- else
- *status = VTBLK_S_IOERR;
- } else
+ if (err == -ENOSYS)
+ *status = VTBLK_S_UNSUPP;
+ else if (err != 0)
+ *status = VTBLK_S_IOERR;
+ else
*status = VTBLK_S_OK;
/*
@@ -320,6 +327,7 @@ pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
/* record fd of storage device/file */
sc->vbsc_fd = fd;
+ sc->vbsc_ischr = S_ISCHR(sbuf.st_mode);
pthread_mutex_init(&sc->vsc_mtx, NULL);
OpenPOWER on IntegriCloud