mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-31 22:11:53 -06:00
nvme: implement the Flush command
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 <hch@lst.de> Acked-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
f3a1b5068c
commit
8b9d74e0ee
2 changed files with 17 additions and 3 deletions
|
@ -207,11 +207,23 @@ static void nvme_rw_cb(void *opaque, int ret)
|
||||||
} else {
|
} else {
|
||||||
req->status = NVME_INTERNAL_DEV_ERROR;
|
req->status = NVME_INTERNAL_DEV_ERROR;
|
||||||
}
|
}
|
||||||
|
if (req->has_sg) {
|
||||||
qemu_sglist_destroy(&req->qsg);
|
qemu_sglist_destroy(&req->qsg);
|
||||||
|
}
|
||||||
nvme_enqueue_req_completion(cq, req);
|
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,
|
static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
|
||||||
NvmeRequest *req)
|
NvmeRequest *req)
|
||||||
{
|
{
|
||||||
|
@ -235,6 +247,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
|
||||||
}
|
}
|
||||||
assert((nlb << data_shift) == req->qsg.size);
|
assert((nlb << data_shift) == req->qsg.size);
|
||||||
|
|
||||||
|
req->has_sg = true;
|
||||||
dma_acct_start(n->conf.blk, &req->acct, &req->qsg,
|
dma_acct_start(n->conf.blk, &req->acct, &req->qsg,
|
||||||
is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
|
is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
|
||||||
req->aiocb = is_write ?
|
req->aiocb = is_write ?
|
||||||
|
@ -256,7 +269,7 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
|
||||||
ns = &n->namespaces[nsid - 1];
|
ns = &n->namespaces[nsid - 1];
|
||||||
switch (cmd->opcode) {
|
switch (cmd->opcode) {
|
||||||
case NVME_CMD_FLUSH:
|
case NVME_CMD_FLUSH:
|
||||||
return NVME_SUCCESS;
|
return nvme_flush(n, ns, cmd, req);
|
||||||
case NVME_CMD_WRITE:
|
case NVME_CMD_WRITE:
|
||||||
case NVME_CMD_READ:
|
case NVME_CMD_READ:
|
||||||
return nvme_rw(n, ns, cmd, req);
|
return nvme_rw(n, ns, cmd, req);
|
||||||
|
|
|
@ -638,6 +638,7 @@ typedef struct NvmeRequest {
|
||||||
struct NvmeSQueue *sq;
|
struct NvmeSQueue *sq;
|
||||||
BlockAIOCB *aiocb;
|
BlockAIOCB *aiocb;
|
||||||
uint16_t status;
|
uint16_t status;
|
||||||
|
bool has_sg;
|
||||||
NvmeCqe cqe;
|
NvmeCqe cqe;
|
||||||
BlockAcctCookie acct;
|
BlockAcctCookie acct;
|
||||||
QEMUSGList qsg;
|
QEMUSGList qsg;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue