From 75584b52ce685510161d2749c2355baa68c58877 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig <chellwig@redhat.com> Date: Tue, 24 Nov 2009 19:43:07 -0200 Subject: [PATCH 09/11] block: add enable_write_cache flag RH-Author: Christoph Hellwig <chellwig@redhat.com> Message-id: <1258670786.11068.0.camel@brick.lst.de> Patchwork-id: 3744 O-Subject: Re: [PATCH 1/5] block: add enable_write_cache flag Bugzilla: 537646 RH-Acked-by: Juan Quintela <quintela@redhat.com> RH-Acked-by: Kevin Wolf <kwolf@redhat.com> RH-Acked-by: Markus Armbruster <armbru@redhat.com> On Wed, 2009-11-18 at 19:23 -0200, Eduardo Habkost wrote: > Is there going to be a respin, to fix this? > > I wouldn't push for scsi to be fixed, as we don't compile it, but having > the default ./configure options building without errors is a good thing > to make developers' lifes easier. > > (There's no need to resend the whole series, you can just send a new > patch as a reply to this one). Here's the updated patch: commit e900a7b748316b5b5a98e41dde36a0cb8e15be5f Author: Christoph Hellwig <hch@lst.de> Date: Fri Sep 4 19:01:15 2009 +0200 block: add enable_write_cache flag Add a enable_write_cache flag in the block driver state, and use it to decide if we claim to have a volatile write cache that needs controlled flushing from the guest. The flag is off if cache=writethrough is defined because O_DSYNC guarantees that every write goes to stable storage, and it is on for cache=none and cache=writeback. Both scsi-disk and ide now use the new flage, changing from their defaults of always off (ide) or always on (scsi-disk). Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/block.c | 15 +++++++++++++++ qemu/block.h | 1 + qemu/block_int.h | 3 +++ qemu/hw/ide.c | 6 +++++- qemu/hw/scsi-disk.c | 4 +++- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/qemu/block.c b/qemu/block.c index 4f8b295..490fb95 100644 --- a/qemu/block.c +++ b/qemu/block.c @@ -454,6 +454,16 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, bs->opaque = qemu_mallocz(drv->instance_size); if (bs->opaque == NULL && drv->instance_size > 0) return -1; + + /* + * Yes, BDRV_O_NOCACHE aka O_DIRECT means we have to present a + * write cache to the guest. We do need the fdatasync to flush + * out transactions for block allocations, and we maybe have a + * volatile write cache in our backing device to deal with. + */ + if (flags & (BDRV_O_CACHE_WB|BDRV_O_NOCACHE)) + bs->enable_write_cache = 1; + /* Note: for compatibility, we open disk image files as RDWR, and RDONLY as fallback */ if (!(flags & BDRV_O_FILE)) @@ -1048,6 +1058,11 @@ int bdrv_is_sg(BlockDriverState *bs) return bs->sg; } +int bdrv_enable_write_cache(BlockDriverState *bs) +{ + return bs->enable_write_cache; +} + /* XXX: no longer used */ void bdrv_set_change_cb(BlockDriverState *bs, void (*change_cb)(void *opaque), void *opaque) diff --git a/qemu/block.h b/qemu/block.h index cab9cba..578d003 100644 --- a/qemu/block.h +++ b/qemu/block.h @@ -130,6 +130,7 @@ int bdrv_get_translation_hint(BlockDriverState *bs); int bdrv_is_removable(BlockDriverState *bs); int bdrv_is_read_only(BlockDriverState *bs); int bdrv_is_sg(BlockDriverState *bs); +int bdrv_enable_write_cache(BlockDriverState *bs); int bdrv_is_inserted(BlockDriverState *bs); int bdrv_media_changed(BlockDriverState *bs); int bdrv_is_locked(BlockDriverState *bs); diff --git a/qemu/block_int.h b/qemu/block_int.h index 5334904..4c2e3b2 100644 --- a/qemu/block_int.h +++ b/qemu/block_int.h @@ -144,6 +144,9 @@ struct BlockDriverState { /* Whether the disk can expand beyond total_sectors */ int growable; + /* do we need to tell the quest if we have a volatile write cache? */ + int enable_write_cache; + /* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs, translation; diff --git a/qemu/hw/ide.c b/qemu/hw/ide.c index abc6b10..d002b01 100644 --- a/qemu/hw/ide.c +++ b/qemu/hw/ide.c @@ -594,7 +594,11 @@ static void ide_identify(IDEState *s) /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); put_le16(p + 84, (1 << 14)); - put_le16(p + 85, (1 << 14)); + /* 14 = NOP supported, 5=WCACHE enabled */ + if (bdrv_enable_write_cache(s->bs)) + put_le16(p + 85, (1 << 14) | (1 << 5)); + else + put_le16(p + 85, (1 << 14)); /* 13=flush_cache_ext,12=flush_cache,10=lba48 */ put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10)); put_le16(p + 87, (1 << 14)); diff --git a/qemu/hw/scsi-disk.c b/qemu/hw/scsi-disk.c index 5991e12..00bcf28 100644 --- a/qemu/hw/scsi-disk.c +++ b/qemu/hw/scsi-disk.c @@ -704,7 +704,9 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, memset(p,0,20); p[0] = 8; p[1] = 0x12; - p[2] = 4; /* WCE */ + if (bdrv_enable_write_cache(s->bdrv)) { + p[2] = 4; /* WCE */ + } p += 20; } if ((page == 0x3f || page == 0x2a) -- 1.6.3.rc4.29.g8146