diff mbox

[3/3] support host sensing of block sizes

Message ID 1335448165-26174-4-git-send-email-borntraeger@de.ibm.com
State New
Headers show

Commit Message

Christian Borntraeger April 26, 2012, 1:49 p.m. UTC
From: Einar Lueck <elelueck@de.ibm.com>

This patch provides a new function to guess physical and logical block
sizes and exploits them in the context of s390 virtio bus. On s390
there may be block sizes different then 512. Therefore, we will
use the new function to setup the physical and logical block size
properly.

The alternative would be to do that unconditionally. There is also
a similar approach (only the sector size) at
https://github.com/bonzini/qemu/commit/d55b867fb6327d365c89effb7fc684459cdb26b6

Signed-off-by: Einar Lueck <elelueck@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 block.c              |   22 ++++++++++++++++++++++
 block.h              |   10 +++++++---
 hw/ide/qdev.c        |    2 +-
 hw/s390-virtio-bus.c |    2 +-
 hw/scsi-disk.c       |    2 +-
 hw/scsi-generic.c    |    2 +-
 hw/usb/dev-storage.c |    2 +-
 hw/virtio-blk.c      |    3 +++
 hw/virtio-pci.c      |    2 +-
 9 files changed, 38 insertions(+), 9 deletions(-)

Comments

Christoph Hellwig April 27, 2012, 1:21 p.m. UTC | #1
On Thu, Apr 26, 2012 at 03:49:25PM +0200, Christian Borntraeger wrote:
> From: Einar Lueck <elelueck@de.ibm.com>
> 
> This patch provides a new function to guess physical and logical block
> sizes and exploits them in the context of s390 virtio bus. On s390
> there may be block sizes different then 512. Therefore, we will
> use the new function to setup the physical and logical block size
> properly.
> 
> The alternative would be to do that unconditionally. There is also
> a similar approach (only the sector size) at
> https://github.com/bonzini/qemu/commit/d55b867fb6327d365c89effb7fc684459cdb26b6

The big problem with autosensing block sizes is that it breaks migration to
hosts with a block device that has a different block size, or between files
and block devices.
diff mbox

Patch

diff --git a/block.c b/block.c
index 8af4d19..bece241 100644
--- a/block.c
+++ b/block.c
@@ -34,6 +34,7 @@ 
 
 #ifdef __linux__
 #include <linux/hdreg.h>
+#include <linux/fs.h>
 #endif
 
 #ifdef CONFIG_BSD
@@ -2053,6 +2054,27 @@  static int guess_disk_lchs(BlockDriverState *bs,
     return -1;
 }
 
+void bdrv_guess_blocksizes(BlockConf *conf)
+{
+#ifdef __linux__
+    int block_size;
+
+    if (bdrv_ioctl(conf->bs, BLKSSZGET, &block_size) == 0) {
+        conf->logical_block_size = (uint16_t) block_size;
+    } else {
+        conf->logical_block_size = BDRV_SECTOR_SIZE;
+    }
+    if (bdrv_ioctl(conf->bs, BLKPBSZGET, &block_size) == 0) {
+        conf->physical_block_size = (uint16_t) block_size;
+    } else {
+        conf->physical_block_size = BDRV_SECTOR_SIZE;
+    }
+#else
+    conf->logical_block_size = BDRV_SECTOR_SIZE;
+    conf->physical_block_size = BDRV_SECTOR_SIZE;
+#endif
+}
+
 void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
 {
     int translation, lba_detected = 0;
diff --git a/block.h b/block.h
index f163e54..8f3c301 100644
--- a/block.h
+++ b/block.h
@@ -429,6 +429,7 @@  typedef struct BlockConf {
     uint32_t opt_io_size;
     int32_t bootindex;
     uint32_t discard_granularity;
+    uint32_t use_host_sizes;
 } BlockConf;
 
 static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -444,7 +445,9 @@  static inline unsigned int get_physical_block_exp(BlockConf *conf)
     return exp;
 }
 
-#define DEFINE_BLOCK_PROPERTIES(_state, _conf)                          \
+void bdrv_guess_blocksizes(BlockConf *conf);
+
+#define DEFINE_BLOCK_PROPERTIES(_state, _conf, _use_host_sizes)         \
     DEFINE_PROP_DRIVE("drive", _state, _conf.bs),                       \
     DEFINE_PROP_BLOCKSIZE("logical_block_size", _state,                 \
                           _conf.logical_block_size, 512),               \
@@ -454,7 +457,8 @@  static inline unsigned int get_physical_block_exp(BlockConf *conf)
     DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0),    \
     DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1),        \
     DEFINE_PROP_UINT32("discard_granularity", _state, \
-                       _conf.discard_granularity, 0)
-
+                       _conf.discard_granularity, 0), \
+    DEFINE_PROP_UINT32("use_host_sizes", _state, \
+                       _conf.use_host_sizes, _use_host_sizes)
 #endif
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index a46578d..27453fa 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -172,7 +172,7 @@  static int ide_drive_initfn(IDEDevice *dev)
 }
 
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
-    DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
+    DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf, 0),     \
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
     DEFINE_PROP_HEX64("wwn",  IDEDrive, dev.wwn, 0),    \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 084bac1..b35faff 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -390,7 +390,7 @@  static TypeInfo s390_virtio_net = {
 };
 
 static Property s390_virtio_blk_properties[] = {
-    DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+    DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block, 1),
     DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a029ab6..785f987 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1912,7 +1912,7 @@  static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
 #endif
 
 #define DEFINE_SCSI_DISK_PROPERTIES()                           \
-    DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),          \
+    DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf, 0),       \
     DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
     DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
 
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index d856d23..d8d17f9 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -482,7 +482,7 @@  static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
 }
 
 static Property scsi_generic_properties[] = {
-    DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
+    DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index d865a5e..ba68568 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -637,7 +637,7 @@  static const VMStateDescription vmstate_usb_msd = {
 };
 
 static Property msd_properties[] = {
-    DEFINE_BLOCK_PROPERTIES(MSDState, conf),
+    DEFINE_BLOCK_PROPERTIES(MSDState, conf, 0),
     DEFINE_PROP_STRING("serial", MSDState, serial),
     DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
     DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 5258533..dc8ba44 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -612,6 +612,9 @@  VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
     s->vdev.reset = virtio_blk_reset;
     s->bs = conf->bs;
     s->conf = conf;
+    if (s->conf->use_host_sizes) {
+        bdrv_guess_blocksizes(s->conf);
+    }
     s->serial = *serial;
     s->rq = NULL;
     s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 4a4413d..a84d2dc 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -814,7 +814,7 @@  static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
 
 static Property virtio_blk_properties[] = {
     DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
-    DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+    DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block, 0),
     DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
     DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
     DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),