Commit aa659be3 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Anthony Liguori
Browse files

virtio-blk: add volatile writecache feature



Add a new VIRTIO_BLK_F_WCACHE feature to virtio-blk to indicate that we have
a volatile write cache that needs controlled flushing.  Implement a
VIRTIO_BLK_T_FLUSH operation to flush it.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent b0484ae4
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -130,6 +130,13 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
}

static void virtio_blk_flush_complete(void *opaque, int ret)
{
    VirtIOBlockReq *req = opaque;

    virtio_blk_req_complete(req, ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK);
}

static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
{
    VirtIOBlockReq *req = qemu_mallocz(sizeof(*req));
@@ -268,6 +275,16 @@ static void do_multiwrite(BlockDriverState *bs, BlockRequest *blkreq,
    }
}

static void virtio_blk_handle_flush(VirtIOBlockReq *req)
{
    BlockDriverAIOCB *acb;

    acb = bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req);
    if (!acb) {
        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
    }
}

static void virtio_blk_handle_write(BlockRequest *blkreq, int *num_writes,
    VirtIOBlockReq *req, BlockDriverState **old_bs)
{
@@ -323,7 +340,9 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
        req->out = (void *)req->elem.out_sg[0].iov_base;
        req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base;

        if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
        if (req->out->type & VIRTIO_BLK_T_FLUSH) {
            virtio_blk_handle_flush(req);
        } else if (req->out->type & VIRTIO_BLK_T_SCSI_CMD) {
            virtio_blk_handle_scsi(req);
        } else if (req->out->type & VIRTIO_BLK_T_OUT) {
            qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
@@ -417,6 +436,9 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev)

    features |= (1 << VIRTIO_BLK_F_SEG_MAX);
    features |= (1 << VIRTIO_BLK_F_GEOMETRY);

    if (bdrv_enable_write_cache(s->bs))
        features |= (1 << VIRTIO_BLK_F_WCACHE);
#ifdef __linux__
    features |= (1 << VIRTIO_BLK_F_SCSI);
#endif
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#define VIRTIO_BLK_F_BLK_SIZE   6       /* Block size of disk is available*/
#define VIRTIO_BLK_F_SCSI       7       /* Supports scsi command passthru */
#define VIRTIO_BLK_F_IDENTIFY   8       /* ATA IDENTIFY supported */
#define VIRTIO_BLK_F_WCACHE     9       /* write cache enabled */

#define VIRTIO_BLK_ID_LEN       256     /* length of identify u16 array */
#define VIRTIO_BLK_ID_SN        10      /* start of char * serial# */
@@ -55,6 +56,9 @@ struct virtio_blk_config
/* This bit says it's a scsi command, not an actual read or write. */
#define VIRTIO_BLK_T_SCSI_CMD   2

/* Flush the volatile write cache */
#define VIRTIO_BLK_T_FLUSH      4

/* Barrier before this op. */
#define VIRTIO_BLK_T_BARRIER    0x80000000