aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-10-31 17:14:41 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2012-11-12 15:00:27 +0100
commitaccfeb2dd32ece73350b06cee1b2403f47e86fe3 (patch)
tree6c4ec5b30d7212df7ffea80053ac0f23b94e6e06 /hw
parent346a3017ec8d5ac4a6961d823f1e576867dc35ef (diff)
scsi-disk: flush cache after disabling it
SBC says that "if an application client changes the WCE bit from one to zero via a MODE SELECT command, then the device server shall write any data in volatile cache to non-volatile medium before completing the command". Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/scsi-disk.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d15f891974..49b5686a92 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1387,6 +1387,7 @@ invalid_param_len:
static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
{
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
uint8_t *p = inbuf;
int cmd = r->req.cmd.buf[0];
int len = r->req.cmd.xfer;
@@ -1423,6 +1424,14 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
return;
}
}
+ if (!bdrv_enable_write_cache(s->qdev.conf.bs)) {
+ /* The request is used as the AIO opaque value, so add a ref. */
+ scsi_req_ref(&r->req);
+ bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
+ r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
+ return;
+ }
+
scsi_req_complete(&r->req, GOOD);
return;