qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/14] Block patches
@ 2010-06-22 14:09 Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 01/14] scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup Kevin Wolf
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit cada87c432e3b9cd55869a24055baf2b7bc0b70c:
  Blue Swirl (1):
        Update OpenBIOS images

are available in the git repository at:

  git://repo.or.cz/qemu/kevin.git for-anthony

Christoph Hellwig (1):
      block: fix physical_block_size calculation

Eduardo Habkost (1):
      monitor: allow device to be ejected if no disk is inserted

Kevin Wolf (8):
      block: Add bdrv_(p)write_sync
      cow: Use bdrv_(p)write_sync for metadata writes
      qcow: Use bdrv_(p)write_sync for metadata writes
      qcow2: Use bdrv_(p)write_sync for metadata writes
      vmdk: Use bdrv_(p)write_sync for metadata writes
      vpc: Use bdrv_(p)write_sync for metadata writes
      qcow2: Fix qemu-img check segfault on corrupted images
      qcow2: Don't try to check tables that couldn't be loaded

MORITA Kazutaka (1):
      qemu-io: check registered fds in command_loop()

Nicholas Bellinger (2):
      scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup
      scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments

Yoshiaki Tamura (1):
      virtio-blk: fix the list operation in virtio_blk_load().

 block.c                |   37 +++++++++++++++++++++++++++++++++++++
 block.h                |    4 ++++
 block/cow.c            |   20 +++++++++++---------
 block/qcow.c           |   18 ++++++++++--------
 block/qcow2-cluster.c  |   24 ++++++++++++------------
 block/qcow2-refcount.c |   39 ++++++++++++++++++++++++---------------
 block/qcow2-snapshot.c |   23 +++++++++++------------
 block/qcow2.c          |   10 +++++-----
 block/vmdk.c           |   10 +++++-----
 block/vpc.c            |    9 +++++----
 block_int.h            |    4 +++-
 blockdev.c             |   22 ++++++++++------------
 cmd.c                  |   33 ++++++++++++++++++++++++++++++---
 hw/scsi-bus.c          |   11 +++++++++++
 hw/scsi-defs.h         |    2 ++
 hw/virtio-blk.c        |    2 +-
 16 files changed, 181 insertions(+), 87 deletions(-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 01/14] scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 02/14] scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments Kevin Wolf
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch updates hw/scsi-bus.c to add the PERSISTENT_RESERVE_OUT cdb
case in scsi_req_xfer_mode() to set SCSI_XFER_TO_DEV for outgoing WRITE data.

Signed-off-by: Nicholas A. Bellinger <nab@linux-iscsi.org>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi-bus.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 055a94d..3575ba3 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -306,6 +306,7 @@ static void scsi_req_xfer_mode(SCSIRequest *req)
     case MEDIUM_SCAN:
     case SEND_VOLUME_TAG:
     case WRITE_LONG_2:
+    case PERSISTENT_RESERVE_OUT:
         req->cmd.mode = SCSI_XFER_TO_DEV;
         break;
     default:
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 02/14] scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 01/14] scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 03/14] block: fix physical_block_size calculation Kevin Wolf
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch updates hw/scsi-bus.c to add MAINTENANCE_IN and MAINTENANCE_OUT case in
scsi_req_length() for TYPE_ROM with MMC commands.  It also adds the MAINTENANCE_OUT
case in scsi_req_xfer_mode() to set SCSI_XFER_TO_DEV for outgoing write data.

Signed-off-by: Nicholas A. Bellinger <nab@linux-iscsi.org>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi-bus.c  |   10 ++++++++++
 hw/scsi-defs.h |    2 ++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 3575ba3..24bd060 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -242,6 +242,13 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
     case INQUIRY:
         req->cmd.xfer = cmd[4] | (cmd[3] << 8);
         break;
+    case MAINTENANCE_OUT:
+    case MAINTENANCE_IN:
+        if (req->dev->type == TYPE_ROM) {
+            /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */
+            req->cmd.xfer = cmd[9] | (cmd[8] << 8);
+        }
+        break;
     }
     return 0;
 }
@@ -307,6 +314,7 @@ static void scsi_req_xfer_mode(SCSIRequest *req)
     case SEND_VOLUME_TAG:
     case WRITE_LONG_2:
     case PERSISTENT_RESERVE_OUT:
+    case MAINTENANCE_OUT:
         req->cmd.mode = SCSI_XFER_TO_DEV;
         break;
     default:
@@ -387,6 +395,8 @@ static const char *scsi_command_name(uint8_t cmd)
         [ SPACE                    ] = "SPACE",
         [ INQUIRY                  ] = "INQUIRY",
         [ RECOVER_BUFFERED_DATA    ] = "RECOVER_BUFFERED_DATA",
+        [ MAINTENANCE_IN           ] = "MAINTENANCE_IN",
+        [ MAINTENANCE_OUT          ] = "MAINTENANCE_OUT",
         [ MODE_SELECT              ] = "MODE_SELECT",
         [ RESERVE                  ] = "RESERVE",
         [ RELEASE                  ] = "RELEASE",
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index 5890094..a4a3518 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -84,6 +84,8 @@
 #define MODE_SENSE_10         0x5a
 #define PERSISTENT_RESERVE_IN 0x5e
 #define PERSISTENT_RESERVE_OUT 0x5f
+#define MAINTENANCE_IN        0xa3
+#define MAINTENANCE_OUT       0xa4
 #define MOVE_MEDIUM           0xa5
 #define READ_12               0xa8
 #define WRITE_12              0xaa
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 03/14] block: fix physical_block_size calculation
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 01/14] scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 02/14] scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 04/14] monitor: allow device to be ejected if no disk is inserted Kevin Wolf
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Christoph Hellwig <hch@lst.de>

Both SCSI and virtio expect the physical block size relative to the
logical block size.  So get the factor first before calculating the
log2.

Reported-by: Mike Cao <bcao@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block_int.h |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/block_int.h b/block_int.h
index e3bfd19..b64a009 100644
--- a/block_int.h
+++ b/block_int.h
@@ -224,7 +224,9 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
 {
     unsigned int exp = 0, size;
 
-    for (size = conf->physical_block_size; size > 512; size >>= 1) {
+    for (size = conf->physical_block_size;
+        size > conf->logical_block_size;
+        size >>= 1) {
         exp++;
     }
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 04/14] monitor: allow device to be ejected if no disk is inserted
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (2 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 03/14] block: fix physical_block_size calculation Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 05/14] block: Add bdrv_(p)write_sync Kevin Wolf
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Eduardo Habkost <ehabkost@redhat.com>

This changes the monitor eject_device() function to not check for
bdrv_is_inserted().

Example run where the bug manifests itself:

(output of 'info block' is stripped to include only the CD-ROM device)

  (qemu) info block
  ide1-cd0: type=cdrom removable=1 locked=0 [not inserted]
  (qemu) change ide1-cd0 /dev/cdrom host_cdrom
  (qemu) info block
  ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=1 drv=host_cdrom encrypted=0
  (qemu) eject ide1-cd0
  (qemu) info block
  ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=1 drv=host_cdrom encrypted=0

  # at this point, a disk was inserted on the host CD-ROM drive

  (qemu) info block
  ide1-cd0: type=cdrom removable=1 locked=0 file=/dev/cdrom ro=1 drv=host_cdrom encrypted=0
  (qemu) eject ide1-cd0
  (qemu) info block
  ide1-cd0: type=cdrom removable=1 locked=0 [not inserted]
  (qemu)

The first eject command didn't work because the is_inserted() check
failed.

I have no clue why the code had the is_inserted() check, as it doesn't matter
if there is a disk present at the host drive, when the user wants the virtual
device to be disconnected from the host device.

The is_inserted() check has another side effect: a memory leak if the "change"
command is used multiple times, as do_change() calls eject_device() before
re-opening the block device, but bdrv_close() is never called.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 blockdev.c |   22 ++++++++++------------
 1 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index b376884..3b8c606 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -503,20 +503,18 @@ void do_commit(Monitor *mon, const QDict *qdict)
 
 static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
 {
-    if (bdrv_is_inserted(bs)) {
-        if (!force) {
-            if (!bdrv_is_removable(bs)) {
-                qerror_report(QERR_DEVICE_NOT_REMOVABLE,
-                               bdrv_get_device_name(bs));
-                return -1;
-            }
-            if (bdrv_is_locked(bs)) {
-                qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
-                return -1;
-            }
+    if (!force) {
+        if (!bdrv_is_removable(bs)) {
+            qerror_report(QERR_DEVICE_NOT_REMOVABLE,
+                           bdrv_get_device_name(bs));
+            return -1;
+        }
+        if (bdrv_is_locked(bs)) {
+            qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
+            return -1;
         }
-        bdrv_close(bs);
     }
+    bdrv_close(bs);
     return 0;
 }
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 05/14] block: Add bdrv_(p)write_sync
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (3 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 04/14] monitor: allow device to be ejected if no disk is inserted Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 06/14] cow: Use bdrv_(p)write_sync for metadata writes Kevin Wolf
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Add new functions that write and flush the written data to disk immediately.
This is what needs to be used for image format metadata to maintain integrity
for cache=... modes that don't use O_DSYNC. (Actually, we only need barriers,
and therefore the functions are defined as such, but flushes is what is
implemented in this patch - we can try to change that later)

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   37 +++++++++++++++++++++++++++++++++++++
 block.h |    4 ++++
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 3fc2969..e71a771 100644
--- a/block.c
+++ b/block.c
@@ -1010,6 +1010,43 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
     return count1;
 }
 
+/*
+ * Writes to the file and ensures that no writes are reordered across this
+ * request (acts as a barrier)
+ *
+ * Returns 0 on success, -errno in error cases.
+ */
+int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
+    const void *buf, int count)
+{
+    int ret;
+
+    ret = bdrv_pwrite(bs, offset, buf, count);
+    if (ret < 0) {
+        return ret;
+    }
+
+    /* No flush needed for cache=writethrough, it uses O_DSYNC */
+    if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) {
+        bdrv_flush(bs);
+    }
+
+    return 0;
+}
+
+/*
+ * Writes to the file and ensures that no writes are reordered across this
+ * request (acts as a barrier)
+ *
+ * Returns 0 on success, -errno in error cases.
+ */
+int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
+    const uint8_t *buf, int nb_sectors)
+{
+    return bdrv_pwrite_sync(bs, BDRV_SECTOR_SIZE * sector_num,
+        buf, BDRV_SECTOR_SIZE * nb_sectors);
+}
+
 /**
  * Truncate file to 'offset' bytes (needed only for file protocols)
  */
diff --git a/block.h b/block.h
index 9df9b38..6a157f4 100644
--- a/block.h
+++ b/block.h
@@ -80,6 +80,10 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
                void *buf, int count);
 int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
                 const void *buf, int count);
+int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
+    const void *buf, int count);
+int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
+    const uint8_t *buf, int nb_sectors);
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 06/14] cow: Use bdrv_(p)write_sync for metadata writes
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (4 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 05/14] block: Add bdrv_(p)write_sync Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 07/14] qcow: " Kevin Wolf
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.
While at it, correct the wrong usage of errno.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/cow.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/block/cow.c b/block/cow.c
index d146434..eedcc48 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -97,17 +97,18 @@ static inline int cow_set_bit(BlockDriverState *bs, int64_t bitnum)
 {
     uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
     uint8_t bitmap;
+    int ret;
 
-    if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) !=
-	    sizeof(bitmap)) {
-       return -errno;
+    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
+    if (ret < 0) {
+       return ret;
     }
 
     bitmap |= (1 << (bitnum % 8));
 
-    if (bdrv_pwrite(bs->file, offset, &bitmap, sizeof(bitmap)) !=
-	    sizeof(bitmap)) {
-       return -errno;
+    ret = bdrv_pwrite_sync(bs->file, offset, &bitmap, sizeof(bitmap));
+    if (ret < 0) {
+       return ret;
     }
     return 0;
 }
@@ -116,10 +117,11 @@ static inline int is_bit_set(BlockDriverState *bs, int64_t bitnum)
 {
     uint64_t offset = sizeof(struct cow_header_v2) + bitnum / 8;
     uint8_t bitmap;
+    int ret;
 
-    if (bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap)) !=
-	    sizeof(bitmap)) {
-       return -errno;
+    ret = bdrv_pread(bs->file, offset, &bitmap, sizeof(bitmap));
+    if (ret < 0) {
+       return ret;
     }
 
     return !!(bitmap & (1 << (bitnum % 8)));
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 07/14] qcow: Use bdrv_(p)write_sync for metadata writes
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (5 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 06/14] cow: Use bdrv_(p)write_sync for metadata writes Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 08/14] qcow2: " Kevin Wolf
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/block/qcow.c b/block/qcow.c
index 449858f..816103d 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -273,8 +273,9 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
         /* update the L1 entry */
         s->l1_table[l1_index] = l2_offset;
         tmp = cpu_to_be64(l2_offset);
-        if (bdrv_pwrite(bs->file, s->l1_table_offset + l1_index * sizeof(tmp),
-                        &tmp, sizeof(tmp)) != sizeof(tmp))
+        if (bdrv_pwrite_sync(bs->file,
+                s->l1_table_offset + l1_index * sizeof(tmp),
+                &tmp, sizeof(tmp)) < 0)
             return 0;
         new_l2_table = 1;
     }
@@ -302,8 +303,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
     l2_table = s->l2_cache + (min_index << s->l2_bits);
     if (new_l2_table) {
         memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
-        if (bdrv_pwrite(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
-            s->l2_size * sizeof(uint64_t))
+        if (bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
+                s->l2_size * sizeof(uint64_t)) < 0)
             return 0;
     } else {
         if (bdrv_pread(bs->file, l2_offset, l2_table, s->l2_size * sizeof(uint64_t)) !=
@@ -368,8 +369,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
         /* update L2 table */
         tmp = cpu_to_be64(cluster_offset);
         l2_table[l2_index] = tmp;
-        if (bdrv_pwrite(bs->file,
-                        l2_offset + l2_index * sizeof(tmp), &tmp, sizeof(tmp)) != sizeof(tmp))
+        if (bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
+                &tmp, sizeof(tmp)) < 0)
             return 0;
     }
     return cluster_offset;
@@ -835,8 +836,9 @@ static int qcow_make_empty(BlockDriverState *bs)
     int ret;
 
     memset(s->l1_table, 0, l1_length);
-    if (bdrv_pwrite(bs->file, s->l1_table_offset, s->l1_table, l1_length) < 0)
-	return -1;
+    if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
+            l1_length) < 0)
+        return -1;
     ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
     if (ret < 0)
         return ret;
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 08/14] qcow2: Use bdrv_(p)write_sync for metadata writes
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (6 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 07/14] qcow: " Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 09/14] vmdk: " Kevin Wolf
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-cluster.c  |   24 ++++++++++++------------
 block/qcow2-refcount.c |   24 ++++++++++++------------
 block/qcow2-snapshot.c |   23 +++++++++++------------
 block/qcow2.c          |   10 +++++-----
 4 files changed, 40 insertions(+), 41 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 5760ad6..166922f 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -64,8 +64,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
     for(i = 0; i < s->l1_size; i++)
         new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
-    ret = bdrv_pwrite(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
-    if (ret != new_l1_size2)
+    ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2);
+    if (ret < 0)
         goto fail;
     for(i = 0; i < s->l1_size; i++)
         new_l1_table[i] = be64_to_cpu(new_l1_table[i]);
@@ -74,8 +74,8 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE);
     cpu_to_be32w((uint32_t*)data, new_l1_size);
     cpu_to_be64w((uint64_t*)(data + 4), new_l1_table_offset);
-    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
-    if (ret != sizeof(data)) {
+    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data));
+    if (ret < 0) {
         goto fail;
     }
     qemu_free(s->l1_table);
@@ -87,7 +87,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
  fail:
     qemu_free(new_l1_table);
     qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
-    return ret < 0 ? ret : -EIO;
+    return ret;
 }
 
 void qcow2_l2_cache_reset(BlockDriverState *bs)
@@ -207,7 +207,7 @@ static int write_l1_entry(BlockDriverState *bs, int l1_index)
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
-    ret = bdrv_pwrite(bs->file, s->l1_table_offset + 8 * l1_start_index,
+    ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
         buf, sizeof(buf));
     if (ret < 0) {
         return ret;
@@ -263,7 +263,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
     }
     /* write the l2 table to the file */
     BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
-    ret = bdrv_pwrite(bs->file, l2_offset, l2_table,
+    ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
         s->l2_size * sizeof(uint64_t));
     if (ret < 0) {
         goto fail;
@@ -413,8 +413,8 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
                         &s->aes_encrypt_key);
     }
     BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
-    ret = bdrv_write(bs->file, (cluster_offset >> 9) + n_start,
-                     s->cluster_data, n);
+    ret = bdrv_write_sync(bs->file, (cluster_offset >> 9) + n_start,
+        s->cluster_data, n);
     if (ret < 0)
         return ret;
     return 0;
@@ -631,10 +631,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
 
     BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
     l2_table[l2_index] = cpu_to_be64(cluster_offset);
-    if (bdrv_pwrite(bs->file,
+    if (bdrv_pwrite_sync(bs->file,
                     l2_offset + l2_index * sizeof(uint64_t),
                     l2_table + l2_index,
-                    sizeof(uint64_t)) != sizeof(uint64_t))
+                    sizeof(uint64_t)) < 0)
         return 0;
 
     return cluster_offset;
@@ -655,7 +655,7 @@ static int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table,
     int ret;
 
     BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
-    ret = bdrv_pwrite(bs->file, l2_offset + start_offset,
+    ret = bdrv_pwrite_sync(bs->file, l2_offset + start_offset,
         &l2_table[l2_start_index], len);
     if (ret < 0) {
         return ret;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 41e1da9..c2d0e61 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -44,8 +44,8 @@ static int write_refcount_block(BlockDriverState *bs)
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE);
-    if (bdrv_pwrite(bs->file, s->refcount_block_cache_offset,
-            s->refcount_block_cache, size) != size)
+    if (bdrv_pwrite_sync(bs->file, s->refcount_block_cache_offset,
+            s->refcount_block_cache, size) < 0)
     {
         return -EIO;
     }
@@ -269,7 +269,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
 
     /* Now the new refcount block needs to be written to disk */
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);
-    ret = bdrv_pwrite(bs->file, new_block, s->refcount_block_cache,
+    ret = bdrv_pwrite_sync(bs->file, new_block, s->refcount_block_cache,
         s->cluster_size);
     if (ret < 0) {
         goto fail_block;
@@ -279,7 +279,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
     if (refcount_table_index < s->refcount_table_size) {
         uint64_t data64 = cpu_to_be64(new_block);
         BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
-        ret = bdrv_pwrite(bs->file,
+        ret = bdrv_pwrite_sync(bs->file,
             s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
             &data64, sizeof(data64));
         if (ret < 0) {
@@ -359,7 +359,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
 
     /* Write refcount blocks to disk */
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);
-    ret = bdrv_pwrite(bs->file, meta_offset, new_blocks,
+    ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,
         blocks_clusters * s->cluster_size);
     qemu_free(new_blocks);
     if (ret < 0) {
@@ -372,7 +372,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
-    ret = bdrv_pwrite(bs->file, table_offset, new_table,
+    ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
         table_size * sizeof(uint64_t));
     if (ret < 0) {
         goto fail_table;
@@ -387,7 +387,7 @@ static int64_t alloc_refcount_block(BlockDriverState *bs, int64_t cluster_index)
     cpu_to_be64w((uint64_t*)data, table_offset);
     cpu_to_be32w((uint32_t*)(data + 8), table_clusters);
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);
-    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, refcount_table_offset),
+    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, refcount_table_offset),
         data, sizeof(data));
     if (ret < 0) {
         goto fail_table;
@@ -444,7 +444,7 @@ static int write_refcount_block_entries(BlockDriverState *bs,
     size = (last_index - first_index) << REFCOUNT_SHIFT;
 
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
-    ret = bdrv_pwrite(bs->file,
+    ret = bdrv_pwrite_sync(bs->file,
         refcount_block_offset + (first_index << REFCOUNT_SHIFT),
         &s->refcount_block_cache[first_index], size);
     if (ret < 0) {
@@ -826,8 +826,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                 }
             }
             if (l2_modified) {
-                if (bdrv_pwrite(bs->file,
-                                l2_offset, l2_table, l2_size) != l2_size)
+                if (bdrv_pwrite_sync(bs->file,
+                                l2_offset, l2_table, l2_size) < 0)
                     goto fail;
             }
 
@@ -850,8 +850,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     if (l1_modified) {
         for(i = 0; i < l1_size; i++)
             cpu_to_be64s(&l1_table[i]);
-        if (bdrv_pwrite(bs->file, l1_table_offset, l1_table,
-                        l1_size2) != l1_size2)
+        if (bdrv_pwrite_sync(bs->file, l1_table_offset, l1_table,
+                        l1_size2) < 0)
             goto fail;
         for(i = 0; i < l1_size; i++)
             be64_to_cpus(&l1_table[i]);
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 2a21c17..6228612 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -158,25 +158,25 @@ static int qcow_write_snapshots(BlockDriverState *bs)
         h.id_str_size = cpu_to_be16(id_str_size);
         h.name_size = cpu_to_be16(name_size);
         offset = align_offset(offset, 8);
-        if (bdrv_pwrite(bs->file, offset, &h, sizeof(h)) != sizeof(h))
+        if (bdrv_pwrite_sync(bs->file, offset, &h, sizeof(h)) < 0)
             goto fail;
         offset += sizeof(h);
-        if (bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size) != id_str_size)
+        if (bdrv_pwrite_sync(bs->file, offset, sn->id_str, id_str_size) < 0)
             goto fail;
         offset += id_str_size;
-        if (bdrv_pwrite(bs->file, offset, sn->name, name_size) != name_size)
+        if (bdrv_pwrite_sync(bs->file, offset, sn->name, name_size) < 0)
             goto fail;
         offset += name_size;
     }
 
     /* update the various header fields */
     data64 = cpu_to_be64(snapshots_offset);
-    if (bdrv_pwrite(bs->file, offsetof(QCowHeader, snapshots_offset),
-                    &data64, sizeof(data64)) != sizeof(data64))
+    if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, snapshots_offset),
+                    &data64, sizeof(data64)) < 0)
         goto fail;
     data32 = cpu_to_be32(s->nb_snapshots);
-    if (bdrv_pwrite(bs->file, offsetof(QCowHeader, nb_snapshots),
-                    &data32, sizeof(data32)) != sizeof(data32))
+    if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
+                    &data32, sizeof(data32)) < 0)
         goto fail;
 
     /* free the old snapshot table */
@@ -284,9 +284,8 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     for(i = 0; i < s->l1_size; i++) {
         l1_table[i] = cpu_to_be64(s->l1_table[i]);
     }
-    if (bdrv_pwrite(bs->file, sn->l1_table_offset,
-                    l1_table, s->l1_size * sizeof(uint64_t)) !=
-        (s->l1_size * sizeof(uint64_t)))
+    if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset,
+                    l1_table, s->l1_size * sizeof(uint64_t)) < 0)
         goto fail;
     qemu_free(l1_table);
     l1_table = NULL;
@@ -335,8 +334,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     if (bdrv_pread(bs->file, sn->l1_table_offset,
                    s->l1_table, l1_size2) != l1_size2)
         goto fail;
-    if (bdrv_pwrite(bs->file, s->l1_table_offset,
-                    s->l1_table, l1_size2) != l1_size2)
+    if (bdrv_pwrite_sync(bs->file, s->l1_table_offset,
+                    s->l1_table, l1_size2) < 0)
         goto fail;
     for(i = 0;i < s->l1_size; i++) {
         be64_to_cpus(&s->l1_table[i]);
diff --git a/block/qcow2.c b/block/qcow2.c
index 33fa9a9..d29e6b6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -735,7 +735,7 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
         backing_file_offset = sizeof(QCowHeader) + offset;
     }
 
-    ret = bdrv_pwrite(bs->file, sizeof(QCowHeader), buf, ext_size);
+    ret = bdrv_pwrite_sync(bs->file, sizeof(QCowHeader), buf, ext_size);
     if (ret < 0) {
         goto fail;
     }
@@ -744,13 +744,13 @@ static int qcow2_update_ext_header(BlockDriverState *bs,
     uint64_t be_backing_file_offset = cpu_to_be64(backing_file_offset);
     uint32_t be_backing_file_size = cpu_to_be32(backing_file_len);
 
-    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_offset),
+    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, backing_file_offset),
         &be_backing_file_offset, sizeof(uint64_t));
     if (ret < 0) {
         goto fail;
     }
 
-    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, backing_file_size),
+    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, backing_file_size),
         &be_backing_file_size, sizeof(uint32_t));
     if (ret < 0) {
         goto fail;
@@ -1131,8 +1131,8 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
 
     /* write updated header.size */
     offset = cpu_to_be64(offset);
-    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, size),
-                      &offset, sizeof(uint64_t));
+    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
+                           &offset, sizeof(uint64_t));
     if (ret < 0) {
         return ret;
     }
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 09/14] vmdk: Use bdrv_(p)write_sync for metadata writes
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (7 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 08/14] qcow2: " Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 10/14] vpc: " Kevin Wolf
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index e659908..2d4ba42 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -150,7 +150,7 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
         pstrcat(desc, sizeof(desc), tmp_desc);
     }
 
-    if (bdrv_pwrite(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
+    if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0)
         return -1;
     return 0;
 }
@@ -471,14 +471,14 @@ static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
     BDRVVmdkState *s = bs->opaque;
 
     /* update L2 table */
-    if (bdrv_pwrite(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
-                    &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
+    if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+                    &(m_data->offset), sizeof(m_data->offset)) < 0)
         return -1;
     /* update backup L2 table */
     if (s->l1_backup_table_offset != 0) {
         m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
-        if (bdrv_pwrite(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
-                        &(m_data->offset), sizeof(m_data->offset)) != sizeof(m_data->offset))
+        if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
+                        &(m_data->offset), sizeof(m_data->offset)) < 0)
             return -1;
     }
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 10/14] vpc: Use bdrv_(p)write_sync for metadata writes
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (8 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 09/14] vmdk: " Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 11/14] qemu-io: check registered fds in command_loop() Kevin Wolf
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Use bdrv_(p)write_sync to ensure metadata integrity in case of a crash.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vpc.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index f1f73e2..e50509e 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -261,7 +261,7 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
 
         s->last_bitmap_offset = bitmap_offset;
         memset(bitmap, 0xff, s->bitmap_size);
-        bdrv_pwrite(bs->file, bitmap_offset, bitmap, s->bitmap_size);
+        bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
     }
 
 //    printf("sector: %" PRIx64 ", index: %x, offset: %x, bioff: %" PRIx64 ", bloff: %" PRIx64 "\n",
@@ -311,7 +311,7 @@ static int rewrite_footer(BlockDriverState* bs)
     BDRVVPCState *s = bs->opaque;
     int64_t offset = s->free_data_block_offset;
 
-    ret = bdrv_pwrite(bs->file, offset, s->footer_buf, HEADER_SIZE);
+    ret = bdrv_pwrite_sync(bs->file, offset, s->footer_buf, HEADER_SIZE);
     if (ret < 0)
         return ret;
 
@@ -346,7 +346,8 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
 
     // Initialize the block's bitmap
     memset(bitmap, 0xff, s->bitmap_size);
-    bdrv_pwrite(bs->file, s->free_data_block_offset, bitmap, s->bitmap_size);
+    bdrv_pwrite_sync(bs->file, s->free_data_block_offset, bitmap,
+        s->bitmap_size);
 
     // Write new footer (the old one will be overwritten)
     s->free_data_block_offset += s->block_size + s->bitmap_size;
@@ -357,7 +358,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
     // Write BAT entry to disk
     bat_offset = s->bat_offset + (4 * index);
     bat_value = be32_to_cpu(s->pagetable[index]);
-    ret = bdrv_pwrite(bs->file, bat_offset, &bat_value, 4);
+    ret = bdrv_pwrite_sync(bs->file, bat_offset, &bat_value, 4);
     if (ret < 0)
         goto fail;
 
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 11/14] qemu-io: check registered fds in command_loop()
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (9 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 10/14] vpc: " Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 12/14] virtio-blk: fix the list operation in virtio_blk_load() Kevin Wolf
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>

Some block drivers use an aio handler and do I/O completion routines
in it.  However, the handler is not invoked if we only do
aio_read/write, because registered fds are not checked at all.

This patch registers an aio handler of STDIO to checks whether we can
read a command without blocking, and calls qemu_aio_wait() in
command_loop().  Any other handlers can be invoked when user input is
idle.

Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 cmd.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/cmd.c b/cmd.c
index 2336334..db2c9c4 100644
--- a/cmd.c
+++ b/cmd.c
@@ -24,6 +24,7 @@
 #include <getopt.h>
 
 #include "cmd.h"
+#include "qemu-aio.h"
 
 #define _(x)	x	/* not gettext support yet */
 
@@ -149,10 +150,20 @@ add_args_command(
 	args_func = af;
 }
 
+static void prep_fetchline(void *opaque)
+{
+    int *fetchable = opaque;
+
+    qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
+    *fetchable= 1;
+}
+
+static char *get_prompt(void);
+
 void
 command_loop(void)
 {
-	int		c, i, j = 0, done = 0;
+	int		c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
 	char		*input;
 	char		**v;
 	const cmdinfo_t	*ct;
@@ -186,7 +197,21 @@ command_loop(void)
 		free(cmdline);
 		return;
 	}
+
 	while (!done) {
+        if (!prompted) {
+            printf("%s", get_prompt());
+            fflush(stdout);
+            qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL,
+                                    NULL, &fetchable);
+            prompted = 1;
+        }
+
+        qemu_aio_wait();
+
+        if (!fetchable) {
+            continue;
+        }
 		if ((input = fetchline()) == NULL)
 			break;
 		v = breakline(input, &c);
@@ -199,7 +224,11 @@ command_loop(void)
 					v[0]);
 		}
 		doneline(input, v);
+
+        prompted = 0;
+        fetchable = 0;
 	}
+    qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
 }
 
 /* from libxcmd/input.c */
@@ -270,8 +299,6 @@ fetchline(void)
 
 	if (!line)
 		return NULL;
-	printf("%s", get_prompt());
-	fflush(stdout);
 	if (!fgets(line, MAXREADLINESZ, stdin)) {
 		free(line);
 		return NULL;
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 12/14] virtio-blk: fix the list operation in virtio_blk_load().
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (10 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 11/14] qemu-io: check registered fds in command_loop() Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 13/14] qcow2: Fix qemu-img check segfault on corrupted images Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 14/14] qcow2: Don't try to check tables that couldn't be loaded Kevin Wolf
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>

Although it is really rare to get in to the while loop, the list
operation in the loop is obviously wrong.

Signed-off-by: Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/virtio-blk.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 75878eb..0bf929a 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -470,7 +470,7 @@ static int virtio_blk_load(QEMUFile *f, void *opaque, int version_id)
         VirtIOBlockReq *req = virtio_blk_alloc_request(s);
         qemu_get_buffer(f, (unsigned char*)&req->elem, sizeof(req->elem));
         req->next = s->rq;
-        s->rq = req->next;
+        s->rq = req;
     }
 
     return 0;
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 13/14] qcow2: Fix qemu-img check segfault on corrupted images
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (11 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 12/14] virtio-blk: fix the list operation in virtio_blk_load() Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 14/14] qcow2: Don't try to check tables that couldn't be loaded Kevin Wolf
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

With corrupted images, we can easily get an cluster index that exceeds the
array size of the temporary refcount table.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-refcount.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index c2d0e61..cedf57e 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1140,22 +1140,30 @@ int qcow2_check_refcounts(BlockDriverState *bs)
                   s->refcount_table_offset,
                   s->refcount_table_size * sizeof(uint64_t));
     for(i = 0; i < s->refcount_table_size; i++) {
-        int64_t offset;
+        uint64_t offset, cluster;
         offset = s->refcount_table[i];
+        cluster = offset >> s->cluster_bits;
 
         /* Refcount blocks are cluster aligned */
         if (offset & (s->cluster_size - 1)) {
             fprintf(stderr, "ERROR refcount block %d is not "
                 "cluster aligned; refcount table entry corrupted\n", i);
             errors++;
+            continue;
+        }
+
+        if (cluster >= nb_clusters) {
+            fprintf(stderr, "ERROR refcount block %d is outside image\n", i);
+            errors++;
+            continue;
         }
 
         if (offset != 0) {
             errors += inc_refcounts(bs, refcount_table, nb_clusters,
                           offset, s->cluster_size);
-            if (refcount_table[offset / s->cluster_size] != 1) {
+            if (refcount_table[cluster] != 1) {
                 fprintf(stderr, "ERROR refcount block %d refcount=%d\n",
-                    i, refcount_table[offset / s->cluster_size]);
+                    i, refcount_table[cluster]);
             }
         }
     }
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH 14/14] qcow2: Don't try to check tables that couldn't be loaded
  2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
                   ` (12 preceding siblings ...)
  2010-06-22 14:09 ` [Qemu-devel] [PATCH 13/14] qcow2: Fix qemu-img check segfault on corrupted images Kevin Wolf
@ 2010-06-22 14:09 ` Kevin Wolf
  13 siblings, 0 replies; 15+ messages in thread
From: Kevin Wolf @ 2010-06-22 14:09 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Trying to check them leads to a second error message which is more confusing
than helpful:

    Can't get refcount for cluster 0: Invalid argument
    ERROR cluster 0 refcount=-22 reference=1

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/qcow2-refcount.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index cedf57e..4a96d98 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1174,6 +1174,7 @@ int qcow2_check_refcounts(BlockDriverState *bs)
         if (refcount1 < 0) {
             fprintf(stderr, "Can't get refcount for cluster %d: %s\n",
                 i, strerror(-refcount1));
+            continue;
         }
 
         refcount2 = refcount_table[i];
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2010-06-22 14:10 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-22 14:09 [Qemu-devel] [PULL 00/14] Block patches Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 01/14] scsi-bus: Add PERSISTENT_RESERVE_OUT SCSIRequest->cmd.mode setup Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 02/14] scsi-bus: Add MAINTENANCE_IN and MAINTENANCE_OUT SCSIRequest xfer and mode assignments Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 03/14] block: fix physical_block_size calculation Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 04/14] monitor: allow device to be ejected if no disk is inserted Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 05/14] block: Add bdrv_(p)write_sync Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 06/14] cow: Use bdrv_(p)write_sync for metadata writes Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 07/14] qcow: " Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 08/14] qcow2: " Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 09/14] vmdk: " Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 10/14] vpc: " Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 11/14] qemu-io: check registered fds in command_loop() Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 12/14] virtio-blk: fix the list operation in virtio_blk_load() Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 13/14] qcow2: Fix qemu-img check segfault on corrupted images Kevin Wolf
2010-06-22 14:09 ` [Qemu-devel] [PATCH 14/14] qcow2: Don't try to check tables that couldn't be loaded Kevin Wolf

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).