qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	John Snow <jsnow@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PULL 26/26] ide: Add resize callback to ide/core
Date: Fri,  5 Sep 2014 17:13:54 +0100	[thread overview]
Message-ID: <1409933634-11331-27-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1409933634-11331-1-git-send-email-stefanha@redhat.com>

From: John Snow <jsnow@redhat.com>

Currently, if the block device backing the IDE drive is resized,
the information about the device as cached inside of the IDEState
structure is not updated, thus when a guest OS re-queries the drive,
it is unable to see the expanded size.

This patch adds a resize callback that updates the IDENTIFY data
buffer in order to correct this.

Lastly, a Linux guest as-is cannot resize a libata drive while in-use,
but it can see the expanded size as part of a bus rescan event.
This patch also allows guests such as Linux to see the new drive size
after a soft reboot event, without having to exit the QEMU process.

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/ide/core.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 10 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index e0232d4..191f893 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -75,6 +75,17 @@ static void put_le16(uint16_t *p, unsigned int v)
     *p = cpu_to_le16(v);
 }
 
+static void ide_identify_size(IDEState *s)
+{
+    uint16_t *p = (uint16_t *)s->identify_data;
+    put_le16(p + 60, s->nb_sectors);
+    put_le16(p + 61, s->nb_sectors >> 16);
+    put_le16(p + 100, s->nb_sectors);
+    put_le16(p + 101, s->nb_sectors >> 16);
+    put_le16(p + 102, s->nb_sectors >> 32);
+    put_le16(p + 103, s->nb_sectors >> 48);
+}
+
 static void ide_identify(IDEState *s)
 {
     uint16_t *p;
@@ -115,8 +126,8 @@ static void ide_identify(IDEState *s)
     put_le16(p + 58, oldsize >> 16);
     if (s->mult_sectors)
         put_le16(p + 59, 0x100 | s->mult_sectors);
-    put_le16(p + 60, s->nb_sectors);
-    put_le16(p + 61, s->nb_sectors >> 16);
+    /* *(p + 60) := nb_sectors       -- see ide_identify_size */
+    /* *(p + 61) := nb_sectors >> 16 -- see ide_identify_size */
     put_le16(p + 62, 0x07); /* single word dma0-2 supported */
     put_le16(p + 63, 0x07); /* mdma0-2 supported */
     put_le16(p + 64, 0x03); /* pio3-4 supported */
@@ -161,10 +172,10 @@ static void ide_identify(IDEState *s)
     }
     put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
     put_le16(p + 93, 1 | (1 << 14) | 0x2000);
-    put_le16(p + 100, s->nb_sectors);
-    put_le16(p + 101, s->nb_sectors >> 16);
-    put_le16(p + 102, s->nb_sectors >> 32);
-    put_le16(p + 103, s->nb_sectors >> 48);
+    /* *(p + 100) := nb_sectors       -- see ide_identify_size */
+    /* *(p + 101) := nb_sectors >> 16 -- see ide_identify_size */
+    /* *(p + 102) := nb_sectors >> 32 -- see ide_identify_size */
+    /* *(p + 103) := nb_sectors >> 48 -- see ide_identify_size */
 
     if (dev && dev->conf.physical_block_size)
         put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
@@ -179,6 +190,7 @@ static void ide_identify(IDEState *s)
         put_le16(p + 169, 1); /* TRIM support */
     }
 
+    ide_identify_size(s);
     s->identify_set = 1;
 
 fill_buffer:
@@ -253,6 +265,15 @@ fill_buffer:
     memcpy(s->io_buffer, p, sizeof(s->identify_data));
 }
 
+static void ide_cfata_identify_size(IDEState *s)
+{
+    uint16_t *p = (uint16_t *)s->identify_data;
+    put_le16(p + 7, s->nb_sectors >> 16);  /* Sectors per card */
+    put_le16(p + 8, s->nb_sectors);        /* Sectors per card */
+    put_le16(p + 60, s->nb_sectors);       /* Total LBA sectors */
+    put_le16(p + 61, s->nb_sectors >> 16); /* Total LBA sectors */
+}
+
 static void ide_cfata_identify(IDEState *s)
 {
     uint16_t *p;
@@ -270,8 +291,8 @@ static void ide_cfata_identify(IDEState *s)
     put_le16(p + 1, s->cylinders);		/* Default cylinders */
     put_le16(p + 3, s->heads);			/* Default heads */
     put_le16(p + 6, s->sectors);		/* Default sectors per track */
-    put_le16(p + 7, s->nb_sectors >> 16);	/* Sectors per card */
-    put_le16(p + 8, s->nb_sectors);		/* Sectors per card */
+    /* *(p + 7) := nb_sectors >> 16 -- see ide_cfata_identify_size */
+    /* *(p + 8) := nb_sectors       -- see ide_cfata_identify_size */
     padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
     put_le16(p + 22, 0x0004);			/* ECC bytes */
     padstr((char *) (p + 23), s->version, 8);	/* Firmware Revision */
@@ -292,8 +313,8 @@ static void ide_cfata_identify(IDEState *s)
     put_le16(p + 58, cur_sec >> 16);		/* Current capacity */
     if (s->mult_sectors)			/* Multiple sector setting */
         put_le16(p + 59, 0x100 | s->mult_sectors);
-    put_le16(p + 60, s->nb_sectors);		/* Total LBA sectors */
-    put_le16(p + 61, s->nb_sectors >> 16);	/* Total LBA sectors */
+    /* *(p + 60) := nb_sectors       -- see ide_cfata_identify_size */
+    /* *(p + 61) := nb_sectors >> 16 -- see ide_cfata_identify_size */
     put_le16(p + 63, 0x0203);			/* Multiword DMA capability */
     put_le16(p + 64, 0x0001);			/* Flow Control PIO support */
     put_le16(p + 65, 0x0096);			/* Min. Multiword DMA cycle */
@@ -313,6 +334,7 @@ static void ide_cfata_identify(IDEState *s)
     put_le16(p + 160, 0x8100);			/* Power requirement */
     put_le16(p + 161, 0x8001);			/* CF command set */
 
+    ide_cfata_identify_size(s);
     s->identify_set = 1;
 
 fill_buffer:
@@ -2131,6 +2153,28 @@ static bool ide_cd_is_medium_locked(void *opaque)
     return ((IDEState *)opaque)->tray_locked;
 }
 
+static void ide_resize_cb(void *opaque)
+{
+    IDEState *s = opaque;
+    uint64_t nb_sectors;
+
+    if (!s->identify_set) {
+        return;
+    }
+
+    bdrv_get_geometry(s->bs, &nb_sectors);
+    s->nb_sectors = nb_sectors;
+
+    /* Update the identify data buffer. */
+    if (s->drive_kind == IDE_CFATA) {
+        ide_cfata_identify_size(s);
+    } else {
+        /* IDE_CD uses a different set of callbacks entirely. */
+        assert(s->drive_kind != IDE_CD);
+        ide_identify_size(s);
+    }
+}
+
 static const BlockDevOps ide_cd_block_ops = {
     .change_media_cb = ide_cd_change_cb,
     .eject_request_cb = ide_cd_eject_request_cb,
@@ -2138,6 +2182,10 @@ static const BlockDevOps ide_cd_block_ops = {
     .is_medium_locked = ide_cd_is_medium_locked,
 };
 
+static const BlockDevOps ide_hd_block_ops = {
+    .resize_cb = ide_resize_cb,
+};
+
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
                    const char *version, const char *serial, const char *model,
                    uint64_t wwn,
@@ -2174,6 +2222,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
             error_report("Can't use a read-only drive");
             return -1;
         }
+        bdrv_set_dev_ops(bs, &ide_hd_block_ops, s);
     }
     if (serial) {
         pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
-- 
1.9.3

  parent reply	other threads:[~2014-09-05 16:15 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 01/26] block: kill tail whitespace in block.c Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 02/26] pflash_cfi01: fixup stale DPRINTF() calls Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 03/26] pflash_cfi01: write flash contents to bdrv on incoming migration Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 04/26] virtio: Import virtio_vring.h Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 05/26] block: Always compile virtio-blk dataplane Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 06/26] tests: Functions bus_foreach and device_find from libqos virtio API Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 07/26] tests: Add virtio device initialization Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 08/26] libqos: Added basic virtqueue support to virtio implementation Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 09/26] libqos: Added indirect descriptor " Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 10/26] libqos: Added test case for configuration changes in virtio-blk test Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 11/26] libqos: Added MSI-X support Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 12/26] libqos: Added EVENT_IDX support Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 13/26] qemu-img: clarify src_cache option documentation Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 14/26] qemu-img: fix rebase " Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 15/26] block/archipelago: Use QEMU atomic builtins Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 16/26] rename parse_enum_option to qapi_enum_parse and make it public Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 17/26] qemu-nbd: add option to set detect-zeroes mode Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 18/26] qemu-nbd: fix indentation and coding style Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 19/26] MAINTAINERS: update sheepdog maintainer Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 20/26] libqos: add a simple first-fit memory allocator Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 21/26] qtest/ide: Uninitialize PC allocator Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 22/26] ide: Add wwn support to IDE-ATAPI drive Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 23/26] vmdk: fix vmdk_parse_extents() extent_file leaks Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 24/26] vmdk: fix buf leak in vmdk_parse_extents() Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 25/26] IDE: Fill the IDENTIFY request consistently Stefan Hajnoczi
2014-09-05 16:13 ` Stefan Hajnoczi [this message]
2014-09-05 16:32 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell

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=1409933634-11331-27-git-send-email-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=peter.maydell@linaro.org \
    --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).