Re: [PATCH] add virtio disk geometry feature

From: Hollis Blanchard
Date: Wed Apr 16 2008 - 17:57:36 EST


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 Blanchard
IBM Linux Technology Center
¢éì®&Þ~º&¶¬–+-±éÝ¥Šw®žË±Êâmébžìdz¹Þ)í…æèw*jg¬±¨¶‰šŽŠÝj/êäz¹ÞŠà2ŠÞ¨è­Ú&¢)ß«a¶Úþø®G«éh®æj:+v‰¨Šwè†Ù>Wš±êÞiÛaxPjØm¶Ÿÿà -»+ƒùdš_