[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/4 V2] scsi-disk: add FUA support for COMPARE_AND_WRITE
From: |
Yaowei Bai |
Subject: |
[PATCH 4/4 V2] scsi-disk: add FUA support for COMPARE_AND_WRITE |
Date: |
Fri, 8 Nov 2019 17:35:41 +0800 |
It is implemented in the blk_aio_pwritev's callback function in a way
similar to its emulation in scsi_write_do_fua function
Signed-off-by: Yaowei Bai <address@hidden>
---
hw/scsi/scsi-disk.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index f9a0267..0731a3b 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -229,6 +229,7 @@ static bool scsi_is_cmd_fua(SCSICommand *cmd)
case WRITE_10:
case WRITE_12:
case WRITE_16:
+ case COMPARE_AND_WRITE:
return (cmd->buf[1] & 8) != 0;
case VERIFY_10:
@@ -1850,10 +1851,17 @@ static void scsi_compare_and_write_complete(void
*opaque, int ret)
}
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
+ if (r->need_fua_emulation) {
+ block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
+ BLOCK_ACCT_FLUSH);
+ r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
+ goto free;
+ }
scsi_req_complete(&r->req, GOOD);
done:
scsi_req_unref(&r->req);
+free:
qemu_vfree(data->iov.iov_base);
g_free(data);
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
@@ -1954,6 +1962,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest
*req, uint8_t *buf)
{
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
+ SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
uint64_t nb_sectors;
uint8_t *outbuf;
int buflen;
@@ -2209,6 +2218,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest
*req, uint8_t *buf)
return 0;
}
assert(!r->req.aiocb);
+ r->need_fua_emulation = sdc->need_fua_emulation(&r->req.cmd);
r->iov.iov_len = MIN(r->buflen, req->cmd.xfer);
if (r->iov.iov_len == 0) {
scsi_req_complete(&r->req, GOOD);
--
1.8.3.1