LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH] add virtio disk geometry feature
@ 2008-04-16 18:56 Ryan Harper
2008-04-16 21:15 ` Rusty Russell
0 siblings, 1 reply; 5+ messages in thread
From: Ryan Harper @ 2008-04-16 18:56 UTC (permalink / raw)
To: virtualization
Cc: Ryan Harper, linux-kernel, kvm-devel, Rusty Russell, Anthony Liguori
From: Ryan Harper <ryanh@us.ibm.com>
Rather than faking up some geometry, allow the backend to push the disk
geometry via virtio pci config option. Keep the old geo code around for
compatibility.
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 0cfbe8c..1d2142a 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -157,10 +157,28 @@ static int virtblk_ioctl(struct inode *inode, struct file *filp,
/* We provide getgeo only to please some old bootloader/partitioning tools */
static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
{
- /* some standard values, similar to sd */
- geo->heads = 1 << 6;
- geo->sectors = 1 << 5;
- geo->cylinders = get_capacity(bd->bd_disk) >> 11;
+ struct virtio_blk *vblk = bd->bd_disk->private_data;
+ int err = 0;
+
+ /* see if the host passed in geometry config */
+ err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,
+ offsetof(struct virtio_blk_config, cylinders),
+ &geo->cylinders);
+
+ /* if host sets geo flag, all 3 values must be present */
+ if (!err) {
+ __virtio_config_val(vblk->vdev,
+ offsetof(struct virtio_blk_config, heads),
+ &geo->heads);
+ __virtio_config_val(vblk->vdev,
+ offsetof(struct virtio_blk_config, sectors),
+ &geo->sectors);
+ } else {
+ /* some standard values, similar to sd */
+ geo->heads = 1 << 6;
+ geo->sectors = 1 << 5;
+ geo->cylinders = get_capacity(bd->bd_disk) >> 11;
+ }
return 0;
}
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
index bca0b10..142c496 100644
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -9,6 +9,7 @@
#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
+#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
struct virtio_blk_config
{
@@ -18,6 +19,12 @@ struct virtio_blk_config
__le32 size_max;
/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
__le32 seg_max;
+ /* cylinders of the device (if VIRTIO_BLK_F_GEOMETRY) */
+ __le16 cylinders;
+ /* heads of the device (if VIRTIO_BLK_F_GEOMETRY) */
+ __u8 heads;
+ /* sectors of the device (if VIRTIO_BLK_F_GEOMETRY) */
+ __u8 sectors;
} __attribute__((packed));
/* These two define direction. */
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] add virtio disk geometry feature
2008-04-16 18:56 [PATCH] add virtio disk geometry feature Ryan Harper
@ 2008-04-16 21:15 ` Rusty Russell
2008-04-16 21:32 ` Anthony Liguori
0 siblings, 1 reply; 5+ messages in thread
From: Rusty Russell @ 2008-04-16 21:15 UTC (permalink / raw)
To: Ryan Harper; +Cc: virtualization, linux-kernel, kvm-devel, Anthony Liguori
On Thursday 17 April 2008 04:56:37 Ryan Harper wrote:
> From: Ryan Harper <ryanh@us.ibm.com>
>
> Rather than faking up some geometry, allow the backend to push the disk
> geometry via virtio pci config option. Keep the old geo code around for
> compatibility.
Hi Ryan,
Looks good! Some brief review below. Mainly just "how I would have done
things" stuff. BTW, does this help in real life? I assume something in
userspace wants it?
> + int err = 0;
> +
> + /* see if the host passed in geometry config */
> + err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,
> + offsetof(struct virtio_blk_config, cylinders),
> + &geo->cylinders);
Unnecessary err initialization. Sometimes gcc catches bugs when you defer
initializations of err to as late as possible (ie. paths where err isn't
set properly), so I tend to do it.
> + /* if host sets geo flag, all 3 values must be present */
> + if (!err) {
> + __virtio_config_val(vblk->vdev,
> + offsetof(struct virtio_blk_config, heads),
> + &geo->heads);
> + __virtio_config_val(vblk->vdev,
> + offsetof(struct virtio_blk_config, sectors),
> + &geo->sectors);
Kind of ugly; we can represent this in the data structure explicitly tho...
> @@ -18,6 +19,12 @@ struct virtio_blk_config
> __le32 size_max;
> /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
> __le32 seg_max;
> + /* cylinders of the device (if VIRTIO_BLK_F_GEOMETRY) */
> + __le16 cylinders;
> + /* heads of the device (if VIRTIO_BLK_F_GEOMETRY) */
> + __u8 heads;
> + /* sectors of the device (if VIRTIO_BLK_F_GEOMETRY) */
> + __u8 sectors;
> } __attribute__((packed));
... using a struct-within-a-struct.
Here's the result:
Subject: add virtio disk geometry feature
Date: Wed, 16 Apr 2008 13:56:37 -0500
From: Ryan Harper <ryanh@us.ibm.com>
Rather than faking up some geometry, allow the backend to push the disk
geometry via virtio pci config option. Keep the old geo code around for
compatibility.
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
Reviewed-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (modified to single struct)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -157,10 +157,25 @@ static int virtblk_ioctl(struct inode *i
/* We provide getgeo only to please some old bootloader/partitioning tools */
static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
{
- /* some standard values, similar to sd */
- geo->heads = 1 << 6;
- geo->sectors = 1 << 5;
- geo->cylinders = get_capacity(bd->bd_disk) >> 11;
+ struct virtio_blk *vblk = bd->bd_disk->private_data;
+ struct virtio_blk_geometry vgeo;
+ int err;
+
+ /* see if the host passed in geometry config */
+ err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,
+ offsetof(struct virtio_blk_config, geometry),
+ &vgeo);
+
+ if (!err) {
+ geo->heads = vgeo.heads;
+ geo->sectors = vgeo.sectors;
+ geo->cylinders = vgeo.cylinders;
+ } else {
+ /* some standard values, similar to sd */
+ geo->heads = 1 << 6;
+ geo->sectors = 1 << 5;
+ geo->cylinders = get_capacity(bd->bd_disk) >> 11;
+ }
return 0;
}
diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h
--- a/include/linux/virtio_blk.h
+++ b/include/linux/virtio_blk.h
@@ -9,6 +9,7 @@
#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */
#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */
#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */
+#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */
struct virtio_blk_config
{
@@ -18,6 +19,12 @@ struct virtio_blk_config
__le32 size_max;
/* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
__le32 seg_max;
+ /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */
+ struct virtio_blk_geometry {
+ __le16 cylinders;
+ __u8 heads;
+ __u8 sectors;
+ } geometry;
} __attribute__((packed));
/* These two define direction. */
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] add virtio disk geometry feature
2008-04-16 21:15 ` Rusty Russell
@ 2008-04-16 21:32 ` Anthony Liguori
2008-04-16 21:57 ` Hollis Blanchard
2008-04-17 14:37 ` Ryan Harper
0 siblings, 2 replies; 5+ messages in thread
From: Anthony Liguori @ 2008-04-16 21:32 UTC (permalink / raw)
To: Rusty Russell
Cc: Ryan Harper, virtualization, linux-kernel, kvm-devel, Hollis Blanchard
Rusty Russell wrote:
> On Thursday 17 April 2008 04:56:37 Ryan Harper wrote:
>
>> From: Ryan Harper <ryanh@us.ibm.com>
>>
>> Rather than faking up some geometry, allow the backend to push the disk
>> geometry via virtio pci config option. Keep the old geo code around for
>> compatibility.
>>
>
> Hi Ryan,
>
> Looks good! Some brief review below. Mainly just "how I would have done
> things" stuff. BTW, does this help in real life? I assume something in
> userspace wants it?
>
Boot loaders (like grub) query the geometry from the kernel to figure
out how to setup the stage1/stage2. We've seen strange issues with grub
thinking it has crazy geometries when installed on a virtio disk (as
opposed to booting from virtio with an existing disk).
Ryan: have you tested a hardy install with your patches? Does it help
when installing to virtio? I could pretty reliably reproduce the
strangeness with a 20GB disk image FWIW.
> diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
> --- a/drivers/block/virtio_blk.c
> +++ b/drivers/block/virtio_blk.c
> @@ -157,10 +157,25 @@ static int virtblk_ioctl(struct inode *i
> /* We provide getgeo only to please some old bootloader/partitioning tools */
> static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
> {
> - /* some standard values, similar to sd */
> - geo->heads = 1 << 6;
> - geo->sectors = 1 << 5;
> - geo->cylinders = get_capacity(bd->bd_disk) >> 11;
> + struct virtio_blk *vblk = bd->bd_disk->private_data;
> + struct virtio_blk_geometry vgeo;
> + int err;
> +
> + /* see if the host passed in geometry config */
> + err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,
> + offsetof(struct virtio_blk_config, geometry),
> + &vgeo);
> +
> + if (!err) {
> + geo->heads = vgeo.heads;
> + geo->sectors = vgeo.sectors;
> + geo->cylinders = vgeo.cylinders;
> + } else {
> + /* some standard values, similar to sd */
> + geo->heads = 1 << 6;
> + geo->sectors = 1 << 5;
> + geo->cylinders = get_capacity(bd->bd_disk) >> 11;
> + }
> return 0;
> }
>
You're probably breaking PPC since the values in the config space are in
little endian format. virtio_config_val does automagic endianness
conversion if the size is 2, 4, or 8. In this case, the structure size
is 4 so the endianness conversion will do the wrong thing.
Magic endianness conversion based on read size is looking pretty evil to
me... Perhaps we need explicit *_val[8,16,32,64]?
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] add virtio disk geometry feature
2008-04-16 21:32 ` Anthony Liguori
@ 2008-04-16 21:57 ` Hollis Blanchard
2008-04-17 14:37 ` Ryan Harper
1 sibling, 0 replies; 5+ messages in thread
From: Hollis Blanchard @ 2008-04-16 21:57 UTC (permalink / raw)
To: Anthony Liguori
Cc: Rusty Russell, Ryan Harper, virtualization, linux-kernel, kvm-devel
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2566 bytes --]
On Wednesday 16 April 2008 16:32:30 Anthony Liguori wrote:> > diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c> > --- a/drivers/block/virtio_blk.c> > +++ b/drivers/block/virtio_blk.c> > @@ -157,10 +157,25 @@ static int virtblk_ioctl(struct inode *i> > Â /* We provide getgeo only to please some old bootloader/partitioning tools */> > Â static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)> > Â {> > -Â Â Â Â Â /* some standard values, similar to sd */> > -Â Â Â Â Â geo->heads = 1 << 6;> > -Â Â Â Â Â geo->sectors = 1 << 5;> > -Â Â Â Â Â geo->cylinders = get_capacity(bd->bd_disk) >> 11;> > +Â Â Â Â Â struct virtio_blk *vblk = bd->bd_disk->private_data;> > +Â Â Â Â Â struct virtio_blk_geometry vgeo;> > +Â Â Â Â Â int err;> > +> > +Â Â Â Â Â /* see if the host passed in geometry config */> > +Â Â Â Â Â err = virtio_config_val(vblk->vdev, VIRTIO_BLK_F_GEOMETRY,> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â offsetof(struct virtio_blk_config, geometry),> > +Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &vgeo);> > +> > +Â Â Â Â Â if (!err) {> > +Â Â Â Â Â Â Â Â Â Â Â Â Â geo->heads = vgeo.heads;> > +Â Â Â Â Â Â Â Â Â Â Â Â Â geo->sectors = vgeo.sectors;> > +Â Â Â Â Â Â Â Â Â Â Â Â Â geo->cylinders = vgeo.cylinders;> > +Â Â Â Â Â } else {> > +Â Â Â Â Â Â Â Â Â Â Â Â Â /* some standard values, similar to sd */> > +Â Â Â Â Â Â Â Â Â Â Â Â Â geo->heads = 1 << 6;> > +Â Â Â Â Â Â Â Â Â Â Â Â Â geo->sectors = 1 << 5;> > +Â Â Â Â Â Â Â Â Â Â Â Â Â geo->cylinders = get_capacity(bd->bd_disk) >> 11;> > +Â Â Â Â Â }> > Â Â Â Â Â Â return 0;> > Â }> > Â > > You're probably breaking PPC since the values in the config space are in > little endian format. Â virtio_config_val does automagic endianness > conversion if the size is 2, 4, or 8. Â In this case, the structure size > is 4 so the endianness conversion will do the wrong thing.
Good catch; byte-swapping an entire structure is a terrible terrible idea.
> Magic endianness conversion based on read size is looking pretty evil to > me... Perhaps we need explicit *_val[8,16,32,64]?
Implicit byteswapping based on access size is the standard way of implementing accessors.
In this case, reading each structure member individually will do the right implicit swapping, rather than trying to load the whole thing as a single access.
-- Hollis BlanchardIBM Linux Technology Centerÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] add virtio disk geometry feature
2008-04-16 21:32 ` Anthony Liguori
2008-04-16 21:57 ` Hollis Blanchard
@ 2008-04-17 14:37 ` Ryan Harper
1 sibling, 0 replies; 5+ messages in thread
From: Ryan Harper @ 2008-04-17 14:37 UTC (permalink / raw)
To: Anthony Liguori
Cc: Rusty Russell, Ryan Harper, virtualization, linux-kernel,
kvm-devel, Hollis Blanchard
* Anthony Liguori <aliguori@us.ibm.com> [2008-04-16 16:33]:
> Rusty Russell wrote:
> >On Thursday 17 April 2008 04:56:37 Ryan Harper wrote:
> >
> >>From: Ryan Harper <ryanh@us.ibm.com>
> >>
> >>Rather than faking up some geometry, allow the backend to push the disk
> >>geometry via virtio pci config option. Keep the old geo code around for
> >>compatibility.
> >>
> >
> >Hi Ryan,
> >
> > Looks good! Some brief review below. Mainly just "how I would have done
> >things" stuff. BTW, does this help in real life? I assume something in
> >userspace wants it?
> >
>
> Boot loaders (like grub) query the geometry from the kernel to figure
> out how to setup the stage1/stage2. We've seen strange issues with grub
> thinking it has crazy geometries when installed on a virtio disk (as
> opposed to booting from virtio with an existing disk).
>
> Ryan: have you tested a hardy install with your patches? Does it help
> when installing to virtio? I could pretty reliably reproduce the
> strangeness with a 20GB disk image FWIW.
I had tested out hardy with a 10G disk and saw nothing out of the
ordinary. Disk size was the expected value and grub had no issues with
it.
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
(512) 838-9253 T/L: 678-9253
ryanh@us.ibm.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-04-17 14:37 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-04-16 18:56 [PATCH] add virtio disk geometry feature Ryan Harper
2008-04-16 21:15 ` Rusty Russell
2008-04-16 21:32 ` Anthony Liguori
2008-04-16 21:57 ` Hollis Blanchard
2008-04-17 14:37 ` Ryan Harper
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).