qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Jens Axboe <qemu@kernel.dk>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 3/3] proper support of FLUSH_CACHE and FLUSH_CACHE_EXT
Date: Wed, 4 Jan 2006 13:16:53 +0100	[thread overview]
Message-ID: <20060104121653.GD3389@suse.de> (raw)
In-Reply-To: <20060104121208.GA3389@suse.de>


Subject: [PATCH] Properly support the ide flush cache commands
From: Jens Axboe <axboe@suse.de>
Date: 1136376567 +0100

Add a ->bdrv_sync() hook to the BlockDriver, as it should know how to
sync the cached state with what is on disk. I updated the raw and dmg
drivers, they just need to fsync() the file descriptor.

This is needed for correctness reasons, as the OS expects drive cached
data to be on platter when FLUSH_CACHE has completed successfully. At
least Linux uses this extensively for journalled file systems, if they
are mounted with the barrier= option.

---

 block-dmg.c |   11 +++++++++++
 block.c     |   19 +++++++++++++++++++
 block_int.h |    1 +
 hw/ide.c    |   18 +++++++++++++++---
 vl.h        |    1 +
 5 files changed, 47 insertions(+), 3 deletions(-)

5a8639e3c23e7e312c5213c15dd40a24eee9b416
diff --git a/block-dmg.c b/block-dmg.c
index 5df7235..486a938 100644
--- a/block-dmg.c
+++ b/block-dmg.c
@@ -269,6 +269,12 @@ static int dmg_read(BlockDriverState *bs
     return 0;
 }
 
+static int dmg_sync(BlockDriverState *bs)
+{
+    BDRVDMGState *s = bs->opaque;
+    return fsync(s->fd);
+}
+
 static void dmg_close(BlockDriverState *bs)
 {
     BDRVDMGState *s = bs->opaque;
@@ -293,5 +299,10 @@ BlockDriver bdrv_dmg = {
     dmg_read,
     NULL,
     dmg_close,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    dmg_sync,
 };
 
diff --git a/block.c b/block.c
index 6924cee..c37f29a 100644
--- a/block.c
+++ b/block.c
@@ -460,6 +460,14 @@ int bdrv_write(BlockDriverState *bs, int
     return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors);
 }
 
+int bdrv_sync(BlockDriverState *bs)
+{
+    if (bs->drv->bdrv_sync)
+	return bs->drv->bdrv_sync(bs);
+
+    return -EIO;
+}
+
 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
 {
     *nb_sectors_ptr = bs->total_sectors;
@@ -752,6 +760,13 @@ static int raw_create(const char *filena
     return 0;
 }
 
+static int raw_sync(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    return fsync(s->fd);
+}
+
+
 BlockDriver bdrv_raw = {
     "raw",
     sizeof(BDRVRawState),
@@ -761,6 +776,10 @@ BlockDriver bdrv_raw = {
     raw_write,
     raw_close,
     raw_create,
+    NULL,
+    NULL,
+    NULL,
+    raw_sync,
 };
 
 void bdrv_init(void)
diff --git a/block_int.h b/block_int.h
index e303816..30e830a 100644
--- a/block_int.h
+++ b/block_int.h
@@ -40,6 +40,7 @@ struct BlockDriver {
                              int nb_sectors, int *pnum);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
     int (*bdrv_make_empty)(BlockDriverState *bs);
+    int (*bdrv_sync)(BlockDriverState *bs);
     struct BlockDriver *next;
 };
 
diff --git a/hw/ide.c b/hw/ide.c
index 6a52347..3aadd9e 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 #include "vl.h"
+#include "block_int.h"
 
 /* debug IDE devices */
 //#define DEBUG_IDE
@@ -422,7 +423,7 @@ static void put_le16(uint16_t *p, unsign
 
 static void ide_identify(IDEState *s)
 {
-    uint16_t *p;
+    uint16_t *p, flush_flags = 0;
     unsigned int oldsize;
     char buf[20];
 
@@ -431,6 +432,10 @@ static void ide_identify(IDEState *s)
 	return;
     }
 
+    /* flush_cache_ext is bit 13, flush_cache is bit 12 */
+    if (s->bs->drv->bdrv_sync)
+	flush_flags = (1 << 13) | (1 << 12);
+
     memset(s->io_buffer, 0, 512);
     p = (uint16_t *)s->io_buffer;
     put_le16(p + 0, 0x0040);
@@ -473,11 +478,11 @@ static void ide_identify(IDEState *s)
     put_le16(p + 81, 0x16); /* conforms to ata5 */
     put_le16(p + 82, (1 << 14));
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
-    put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
+    put_le16(p + 83, (1 << 14) | (1 << 10) | flush_flags);
     put_le16(p + 84, (1 << 14));
     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 + 86, (1 << 14) | (1 << 10) | flush_flags);
     put_le16(p + 87, (1 << 14));
     put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
     put_le16(p + 93, 1 | (1 << 14) | 0x2000);
@@ -1755,6 +1760,13 @@ static void ide_ioport_write(void *opaqu
             break;
         case WIN_FLUSH_CACHE:
         case WIN_FLUSH_CACHE_EXT:
+	    if (s->is_cdrom)
+		goto abort_cmd;
+	    if (bdrv_sync(s->bs))
+		goto abort_cmd;
+	    s->status = READY_STAT;
+            ide_set_irq(s);
+            break;
 	case WIN_STANDBYNOW1:
         case WIN_IDLEIMMEDIATE:
 	    s->status = READY_STAT;
diff --git a/vl.h b/vl.h
index 7a10728..01a1985 100644
--- a/vl.h
+++ b/vl.h
@@ -460,6 +460,7 @@ int bdrv_write(BlockDriverState *bs, int
 void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
 int bdrv_commit(BlockDriverState *bs);
 void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
+int bdrv_sync(BlockDriverState *bs);
 
 #define BDRV_TYPE_HD     0
 #define BDRV_TYPE_CDROM  1
-- 
1.0.GIT

-- 
Jens Axboe

  parent reply	other threads:[~2006-01-04 12:51 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-04 12:12 [Qemu-devel] [PATCH 0/3] qemu ide updates Jens Axboe
2006-01-04 12:12 ` [Qemu-devel] [PATCH 1/3] ide id updates Jens Axboe
2006-01-04 12:13 ` [Qemu-devel] [PATCH 2/3] ide lba48 support Jens Axboe
2006-02-01 22:34   ` Fabrice Bellard
2006-02-02  9:53     ` Jens Axboe
2006-01-04 12:16 ` Jens Axboe [this message]
2006-01-04 21:07   ` [Qemu-devel] [PATCH 3/3] proper support of FLUSH_CACHE and FLUSH_CACHE_EXT Johannes Schindelin
2006-01-05  8:14     ` Jens Axboe
2006-01-05  9:18       ` Jens Axboe
2006-01-05 13:25         ` Johannes Schindelin
2006-01-05 18:07           ` Jens Axboe
2006-01-05 13:11       ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060104121653.GD3389@suse.de \
    --to=qemu@kernel.dk \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).