[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 1/2] nvme: implement the Flush command
From: |
Christoph Hellwig |
Subject: |
[Qemu-block] [PATCH 1/2] nvme: implement the Flush command |
Date: |
Thu, 11 Jun 2015 12:01:38 +0200 |
Implement a real flush instead of faking it. This is especially important
as Qemu assume Write back cashing by default and thus requires a working
cache flush operation for data integrity.
Signed-off-by: Christoph Hellwig <address@hidden>
---
hw/block/nvme.c | 18 +++++++++++++++---
hw/block/nvme.h | 1 +
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 4b6d5e6..6c654d3 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -206,11 +206,22 @@ static void nvme_rw_cb(void *opaque, int ret)
} else {
req->status = NVME_INTERNAL_DEV_ERROR;
}
-
- qemu_sglist_destroy(&req->qsg);
+ if (req->has_sg)
+ qemu_sglist_destroy(&req->qsg);
nvme_enqueue_req_completion(cq, req);
}
+static uint16_t nvme_flush(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
+ NvmeRequest *req)
+{
+ req->has_sg = false;
+ block_acct_start(blk_get_stats(n->conf.blk), &req->acct, 0,
+ BLOCK_ACCT_FLUSH);
+ req->aiocb = blk_aio_flush(n->conf.blk, nvme_rw_cb, req);
+
+ return NVME_NO_COMPLETE;
+}
+
static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
NvmeRequest *req)
{
@@ -234,6 +245,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns,
NvmeCmd *cmd,
}
assert((nlb << data_shift) == req->qsg.size);
+ req->has_sg = true;
dma_acct_start(n->conf.blk, &req->acct, &req->qsg,
is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
req->aiocb = is_write ?
@@ -255,7 +267,7 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd,
NvmeRequest *req)
ns = &n->namespaces[nsid - 1];
switch (cmd->opcode) {
case NVME_CMD_FLUSH:
- return NVME_SUCCESS;
+ return nvme_flush(n, ns, cmd, req);
case NVME_CMD_WRITE:
case NVME_CMD_READ:
return nvme_rw(n, ns, cmd, req);
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index b6ccb65..bf3a3cc 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -638,6 +638,7 @@ typedef struct NvmeRequest {
struct NvmeSQueue *sq;
BlockAIOCB *aiocb;
uint16_t status;
+ bool has_sg;
NvmeCqe cqe;
BlockAcctCookie acct;
QEMUSGList qsg;
--
1.9.1