summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-03-05 15:29:18 +0000
committermav <mav@FreeBSD.org>2015-03-05 15:29:18 +0000
commita34b7ad0d27c5190fe2e182e71e59556e4bc44d8 (patch)
tree281c2e9ce807fbb2915a02ca5466c2661f5ae6b7
parent52d1cb2338c4d77e09c9043588788b2d567fa9c5 (diff)
downloadFreeBSD-src-a34b7ad0d27c5190fe2e182e71e59556e4bc44d8.zip
FreeBSD-src-a34b7ad0d27c5190fe2e182e71e59556e4bc44d8.tar.gz
Implement cache flush for ahci-hd and for virtio-blk over device.
MFC after: 2 weeks
-rw-r--r--usr.sbin/bhyve/block_if.c7
-rw-r--r--usr.sbin/bhyve/pci_virtio_block.c14
2 files changed, 18 insertions, 3 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..77f6127 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];
};
@@ -218,10 +219,12 @@ pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq)
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 +234,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;
@@ -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