From: Paolo Bonzini <pbonzini@redhat.com>
To: Jens Freimann <jfrei@linux.vnet.ibm.com>
Cc: Heinz Graalfs <graalfs@linux.vnet.ibm.com>,
Alexander Graf <agraf@suse.de>,
qemu-devel <qemu-devel@nongnu.org>,
Christian Borntraeger <borntraeger@de.ibm.com>,
Cornelia Huck <cornelia.huck@de.ibm.com>,
Stefan Weinhuber <wein@linux.vnet.ibm.com>,
Einar Lueck <elelueck@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH 2/2] hd-geometry.c: Integrate HDIO_GETGEO in guessing
Date: Mon, 20 Aug 2012 10:50:42 +0200 [thread overview]
Message-ID: <5031FA62.7090402@redhat.com> (raw)
In-Reply-To: <1345016649-4792-3-git-send-email-jfrei@linux.vnet.ibm.com>
Il 15/08/2012 09:44, Jens Freimann ha scritto:
> From: Einar Lueck <elelueck@linux.vnet.ibm.com>
>
> This patch extends the function guess_disk_lchs. If no geo could
> be derived from reading disk content, HDIO_GETGEO ioctl is issued.
> If this is not successful (e.g. image files) geometry is derived
> from the size of the disk (as before). To achieve this, the MSDOS
> partition table reading logic and the translation computation logic
> have been moved into a separate function guess_disk_msdosgeo. The
> HDIO_GETGEO logic is captured in a new function guess_disk_ioctlgeo.
> guess_disk_lchs then encapsulates both (the overall guessing logic).
> The new HDIO_GETGEO logic is required for two use cases:
> a) Support for geometries of Direct Attached Storage Disks (DASD)
> on s390x configured as backing of virtio block devices.
> b) Support for FCP attached SCSI disks that do not yet have a
> partition table. Without this patch, fdisk -l on the host would
> return different results then fdisk -l in the guest.
>
> Signed-off-by: Einar Lueck <elelueck@linux.vnet.ibm.com>
> Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
> ---
> hw/hd-geometry.c | 118 ++++++++++++++++++++++++++++++++++++++-----------------
> 1 file changed, 81 insertions(+), 37 deletions(-)
>
> diff --git a/hw/hd-geometry.c b/hw/hd-geometry.c
> index 1cdb9fb..fc29075 100644
> --- a/hw/hd-geometry.c
> +++ b/hw/hd-geometry.c
> @@ -33,6 +33,10 @@
> #include "block.h"
> #include "hw/block-common.h"
> #include "trace.h"
> +#ifdef __linux__
> +#include <linux/fs.h>
> +#include <linux/hdreg.h>
> +#endif
>
> struct partition {
> uint8_t boot_ind; /* 0x80 - active */
> @@ -47,13 +51,59 @@ struct partition {
> uint32_t nr_sects; /* nr of sectors in partition */
> } QEMU_PACKED;
>
> +static void guess_chs_for_size(BlockDriverState *bs,
> + uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs)
> +{
> + uint64_t nb_sectors;
> + int cylinders;
> +
> + bdrv_get_geometry(bs, &nb_sectors);
> +
> + cylinders = nb_sectors / (16 * 63);
> + if (cylinders > 16383) {
> + cylinders = 16383;
> + } else if (cylinders < 2) {
> + cylinders = 2;
> + }
> + *pcyls = cylinders;
> + *pheads = 16;
> + *psecs = 63;
> +}
> +
> +/* try to get geometry from disk via HDIO_GETGEO ioctl
> + Return 0 if OK, -1 if ioctl does not work (e.g. image file) */
> +static inline int guess_disk_ioctlgeo(BlockDriverState *bs,
> + uint32_t *pcylinders, uint32_t *pheads,
> + uint32_t *psectors, int *ptranslation)
> +{
> +#ifdef __linux__
> + struct hd_geometry geo;
> +
> + if (bdrv_ioctl(bs, HDIO_GETGEO, &geo)) {
> + return -1;
> + }
> +
> + *pheads = geo.heads;
> + *psectors = geo.sectors;
> + *pcylinders = geo.cylinders;
> + *ptranslation = BIOS_ATA_TRANSLATION_NONE;
> + trace_hd_geometry_lchs_guess(bs, *pcylinders, *pheads, *psectors);
> + return 0;
> +#else
> + return -1;
> +#endif
> +}
> +
> +
> /* try to guess the disk logical geometry from the MSDOS partition table.
> Return 0 if OK, -1 if could not guess */
> -static int guess_disk_lchs(BlockDriverState *bs,
> - int *pcylinders, int *pheads, int *psectors)
> +static int guess_disk_msdosgeo(BlockDriverState *bs,
> + uint32_t *pcylinders, uint32_t *pheads,
> + uint32_t *psectors, int *ptranslation)
> {
> uint8_t buf[BDRV_SECTOR_SIZE];
> - int i, heads, sectors, cylinders;
> + int i, translation;
> + uint32_t heads, sectors, cylinders;
> struct partition *p;
> uint32_t nr_sects;
> uint64_t nb_sectors;
> @@ -87,9 +137,26 @@ static int guess_disk_lchs(BlockDriverState *bs,
> if (cylinders < 1 || cylinders > 16383) {
> continue;
> }
> +
> + if (heads > 16) {
> + /* LCHS guess with heads > 16 means that a BIOS LBA
> + translation was active, so a standard physical disk
> + geometry is OK */
> + guess_chs_for_size(bs, &cylinders, &heads, §ors);
> + translation = cylinders * heads <= 131072
> + ? BIOS_ATA_TRANSLATION_LARGE
> + : BIOS_ATA_TRANSLATION_LBA;
> + } else {
> + /* LCHS guess with heads <= 16: use as physical geometry */
> + /* disable any translation to be in sync with
> + the logical geometry */
> + translation = BIOS_ATA_TRANSLATION_NONE;
> + }
> *pheads = heads;
> *psectors = sectors;
> *pcylinders = cylinders;
> + *ptranslation = translation;
> +
> trace_hd_geometry_lchs_guess(bs, cylinders, heads, sectors);
> return 0;
> }
> @@ -97,51 +164,28 @@ static int guess_disk_lchs(BlockDriverState *bs,
> return -1;
> }
>
> -static void guess_chs_for_size(BlockDriverState *bs,
> - uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs)
> -{
> - uint64_t nb_sectors;
> - int cylinders;
> -
> - bdrv_get_geometry(bs, &nb_sectors);
> -
> - cylinders = nb_sectors / (16 * 63);
> - if (cylinders > 16383) {
> - cylinders = 16383;
> - } else if (cylinders < 2) {
> - cylinders = 2;
> +/* try to guess the disk logical geometry
> + Return 0 if OK, -1 if could not guess */
> +static int guess_disk_lchs(BlockDriverState *bs,
> + uint32_t *pcylinders, uint32_t *pheads,
> + uint32_t *psectors, int *ptranslation) {
> + if (!guess_disk_msdosgeo(bs, pcylinders, pheads, psectors, ptranslation)) {
> + return 0;
> }
> - *pcyls = cylinders;
> - *pheads = 16;
> - *psecs = 63;
> +
> + return guess_disk_ioctlgeo(bs, pcylinders, pheads, psectors, ptranslation);
> }
>
> void hd_geometry_guess(BlockDriverState *bs,
> uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
> int *ptrans)
> {
> - int cylinders, heads, secs, translation;
> + int translation;
>
> - if (guess_disk_lchs(bs, &cylinders, &heads, &secs) < 0) {
> + if (guess_disk_lchs(bs, pcyls, pheads, psecs, &translation) < 0) {
> /* no LCHS guess: use a standard physical disk geometry */
> guess_chs_for_size(bs, pcyls, pheads, psecs);
> translation = hd_bios_chs_auto_trans(*pcyls, *pheads, *psecs);
> - } else if (heads > 16) {
> - /* LCHS guess with heads > 16 means that a BIOS LBA
> - translation was active, so a standard physical disk
> - geometry is OK */
> - guess_chs_for_size(bs, pcyls, pheads, psecs);
> - translation = *pcyls * *pheads <= 131072
> - ? BIOS_ATA_TRANSLATION_LARGE
> - : BIOS_ATA_TRANSLATION_LBA;
> - } else {
> - /* LCHS guess with heads <= 16: use as physical geometry */
> - *pcyls = cylinders;
> - *pheads = heads;
> - *psecs = secs;
> - /* disable any translation to be in sync with
> - the logical geometry */
> - translation = BIOS_ATA_TRANSLATION_NONE;
> }
> if (ptrans) {
> *ptrans = translation;
>
Looks good.
Paolo
next prev parent reply other threads:[~2012-08-20 8:50 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-15 7:44 [Qemu-devel] [PATCH 0/2 v2] s390: block size auto-sensing and geometry guessing changes in common code Jens Freimann
2012-08-15 7:44 ` [Qemu-devel] [PATCH 1/2] virtio-block: support auto-sensing of block sizes Jens Freimann
2012-08-20 8:51 ` Paolo Bonzini
2012-08-15 7:44 ` [Qemu-devel] [PATCH 2/2] hd-geometry.c: Integrate HDIO_GETGEO in guessing Jens Freimann
2012-08-20 8:50 ` Paolo Bonzini [this message]
-- strict thread matches above, loose matches on Subject: below --
2012-08-13 10:10 [Qemu-devel] [PATCH 0/2] s390: block size auto-sensing and geometry guessing changes in common code Jens Freimann
2012-08-13 10:10 ` [Qemu-devel] [PATCH 2/2] hd-geometry.c: Integrate HDIO_GETGEO in guessing Jens Freimann
2012-08-13 8:40 [Qemu-devel] [PATCH 0/2] s390: block size auto-sensing and geometry guessing changes in common code Jens Freimann
2012-08-13 8:40 ` [Qemu-devel] [PATCH 2/2] hd-geometry.c: Integrate HDIO_GETGEO in guessing Jens Freimann
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=5031FA62.7090402@redhat.com \
--to=pbonzini@redhat.com \
--cc=agraf@suse.de \
--cc=borntraeger@de.ibm.com \
--cc=cornelia.huck@de.ibm.com \
--cc=elelueck@linux.vnet.ibm.com \
--cc=graalfs@linux.vnet.ibm.com \
--cc=jfrei@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=wein@linux.vnet.ibm.com \
/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).