Patchwork [1/2] virtio-blk: add max sectors feature (qemu)

login
register
mail settings
Submitter Avishay Traeger1
Date Dec. 23, 2009, 3:21 p.m.
Message ID <OF4B1029AA.64B229B3-ONC2257695.005329E5-C2257695.0054585F@il.ibm.com>
Download mbox | patch
Permalink /patch/41675/
State New
Headers show

Comments

Avishay Traeger1 - Dec. 23, 2009, 3:21 p.m.
This is the accompanying qemu patch for the maximum number of total sectors
in an I/O feature.

Please CC me on replies, as I am not subscribed.

Thanks,
Avishay

Signed-off-by: Avishay Traeger <avishay@il.ibm.com>
---

 #define VIRTIO_BLK_ID_SN        10      /* start of char * serial# */
@@ -46,6 +47,7 @@ struct virtio_blk_config
     uint8_t heads;
     uint8_t sectors;
     uint32_t _blk_size;    /* structure pad, currently unused */
+    uint32_t sectors_max;
     uint16_t identify[VIRTIO_BLK_ID_LEN];
 } __attribute__((packed));

Patch

diff --git a/block.c b/block.c
index 3f3496e..9fa97b8 100644
--- a/block.c
+++ b/block.c
@@ -807,6 +807,29 @@  int64_t bdrv_getlength(BlockDriverState *bs)
     return drv->bdrv_getlength(bs);
 }

+/**
+ * Maximum length of an I/O in sectors. Return -1 if not specified.
+ */
+void bdrv_get_max_sectors(BlockDriverState *bs, uint32_t *sectors_max)
+{
+     BlockDriver *drv = bs->drv;
+     if ((!drv) || (!drv->bdrv_get_max_sectors))
+           *sectors_max = -1;
+     else
+           *sectors_max = drv->bdrv_get_max_sectors(bs);
+}
+
+/**
+ * Check if the bdrv driver implements bdrv_get_max_sectors.
+ */
+int bdrv_uses_max_sectors(BlockDriverState *bs)
+{
+     BlockDriver *drv = bs->drv;
+     if ((drv) && (drv->bdrv_get_max_sectors))
+           return 1;
+     return 0;
+}
+
 /* return 0 as number of sectors if no device present or error */
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
 {
diff --git a/block.h b/block.h
index fa51ddf..bcfdfe9 100644
--- a/block.h
+++ b/block.h
@@ -79,6 +79,8 @@  int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
                 const void *buf, int count);
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
+void bdrv_get_max_sectors(BlockDriverState *bs, uint32_t *sectors_max);
+int bdrv_uses_max_sectors(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
 void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads,
int *psecs);
 int bdrv_commit(BlockDriverState *bs);
diff --git a/block_int.h b/block_int.h
index 9a3b2e0..d3726c7 100644
--- a/block_int.h
+++ b/block_int.h
@@ -81,6 +81,7 @@  struct BlockDriver {
     const char *protocol_name;
     int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
     int64_t (*bdrv_getlength)(BlockDriverState *bs);
+    uint32_t (*bdrv_get_max_sectors)(BlockDriverState *bs);
     int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
                                  const uint8_t *buf, int nb_sectors);

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index a2f0639..751f38d 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -416,13 +416,16 @@  static void virtio_blk_update_config(VirtIODevice
*vdev, uint8_t *config)
     struct virtio_blk_config blkcfg;
     uint64_t capacity;
     int cylinders, heads, secs;
+    uint32_t sectors_max;

     bdrv_get_geometry(s->bs, &capacity);
     bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
+    bdrv_get_max_sectors(s->bs, &sectors_max);
     memset(&blkcfg, 0, sizeof(blkcfg));
     stq_raw(&blkcfg.capacity, capacity);
     stl_raw(&blkcfg.seg_max, 128 - 2);
     stw_raw(&blkcfg.cylinders, cylinders);
+    stl_raw(&blkcfg.sectors_max, sectors_max);
     blkcfg.heads = heads;
     blkcfg.sectors = secs;
     blkcfg.size_max = 0;
@@ -451,6 +454,9 @@  static uint32_t virtio_blk_get_features(VirtIODevice
*vdev)
     if (bdrv_is_read_only(s->bs))
         features |= 1 << VIRTIO_BLK_F_RO;

+    if (bdrv_uses_max_sectors(s->bs))
+        features |= 1 << VIRTIO_BLK_F_SECTOR_MAX;
+
     return features;
 }

@@ -494,7 +500,7 @@  VirtIODevice *virtio_blk_init(DeviceState *dev,
DriveInfo *dinfo)
     static int virtio_blk_id;
     char *ps = (char *)drive_get_serial(dinfo->bdrv);
     size_t size = strlen(ps) ? sizeof(struct virtio_blk_config) :
-         offsetof(struct virtio_blk_config, _blk_size);
+         offsetof(struct virtio_blk_config, identify);

     s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                           size,
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 23ad74c..305fc68 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -32,6 +32,7 @@ 
 #define VIRTIO_BLK_F_SCSI       7       /* Supports scsi command passthru
*/
 #define VIRTIO_BLK_F_IDENTIFY   8       /* ATA IDENTIFY supported */
 #define VIRTIO_BLK_F_WCACHE     9       /* write cache enabled */
+#define VIRTIO_BLK_F_SECTOR_MAX    10	/* Maximum total sectors in an I/O */

 #define VIRTIO_BLK_ID_LEN       256     /* length of identify u16 array */