Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 3160499aacb81f6735941eb4c372d87a > files > 242

kvm-83-164.el5_5.30.src.rpm

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