PCI, lguest and s390 can all only support 256-byte configuration space. So, this giant field broke just about everyone. Unfortunately, removing it is not so simple: we don't want to break old userspace, but we're going to want to re-use that part of the struct. So, modern users can #define VIRTIO_BLK_IDENTIFY_DEPRECATED to indicate that they know it's no longer in the config struct, and can use any new features (all new features which add a configuration field will conflict with this deprecated one). Signed-off-by: Rusty Russell <rusty@xxxxxxxxxxxxxxx> --- drivers/block/virtio_blk.c | 20 ++++++++++++++++++-- include/linux/virtio_blk.h | 10 +++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) 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 @@ -1,4 +1,6 @@ //#define DEBUG +/* We want to see new fields: we use our own struct if we fall back to this */ +#define VIRTIO_BLK_IDENTIFY_DEPRECATED #include <linux/spinlock.h> #include <linux/blkdev.h> #include <linux/hdreg.h> @@ -183,8 +185,22 @@ static void do_virtblk_request(struct re vblk->vq->vq_ops->kick(vblk->vq); } -/* return ATA identify data +/* return ATA identify data: deprecated */ +struct virtio_blk_config_deprecated { + /* The capacity (in 512-byte sectors). */ + __u64 capacity; + /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */ + __u32 size_max; + /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ + __u32 seg_max; + /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ + struct virtio_blk_geometry geometry; + /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ + __u32 blk_size; + __u8 identify[VIRTIO_BLK_ID_BYTES]; +} __attribute__((packed)); + static int virtblk_identify(struct gendisk *disk, void *argp) { struct virtio_blk *vblk = disk->private_data; @@ -196,7 +212,7 @@ static int virtblk_identify(struct gendi goto out; err = virtio_config_buf(vblk->vdev, VIRTIO_BLK_F_IDENTIFY, - offsetof(struct virtio_blk_config, identify), opaque, + offsetof(struct virtio_blk_config_deprecated, identify), opaque, VIRTIO_BLK_ID_BYTES); if (err) 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 @@ -13,7 +13,7 @@ #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ #define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ #define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ -#define VIRTIO_BLK_F_IDENTIFY 8 /* ATA IDENTIFY supported */ +#define VIRTIO_BLK_F_IDENTIFY 8 /* ATA IDENTIFY support (deprecated) */ #define VIRTIO_BLK_F_FLUSH 9 /* Cache flush command support */ #define VIRTIO_BLK_ID_BYTES (sizeof(__u16[256])) /* IDENTIFY DATA */ @@ -33,7 +33,15 @@ struct virtio_blk_config { } geometry; /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ __u32 blk_size; +#ifndef VIRTIO_BLK_IDENTIFY_DEPRECATED + /* + * New code shouldn't use this, but it's under the #ifndef so old + * userspace doesn't break. + */ __u8 identify[VIRTIO_BLK_ID_BYTES]; +#else + /* New fields go here: (all new extensions conflict with F_IDENTIFY) */ +#endif } __attribute__((packed)); /* _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/virtualization