Commit 8b9d74e0 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Kevin Wolf
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarKeith Busch <keith.busch@intel.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent f3a1b506
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -207,11 +207,23 @@ static void nvme_rw_cb(void *opaque, int ret)
    } else {
        req->status = NVME_INTERNAL_DEV_ERROR;
    }

    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)
{
@@ -235,6 +247,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 ?
@@ -256,7 +269,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);
+1 −0
Original line number Diff line number Diff line
@@ -638,6 +638,7 @@ typedef struct NvmeRequest {
    struct NvmeSQueue       *sq;
    BlockAIOCB              *aiocb;
    uint16_t                status;
    bool                    has_sg;
    NvmeCqe                 cqe;
    BlockAcctCookie         acct;
    QEMUSGList              qsg;