Re: [Qemu-devel] [PATCH 2/4] blocksize: support auto-sensing of blocksizes

2014-09-03 Thread Stefan Hajnoczi
On Tue, Jul 29, 2014 at 02:27:17PM +0200, Ekaterina Tumanova wrote:
> The block device model does not impose fixed block sizes for
> access to backing devices. This patch introduces support for
> auto lookup of the block sizes of the backing block device.
> 
> To achieve this, a new function blkconf_blocksizes is
> implemented. This function tries to get values
> from the block driver. If this does not work 512 is used,
> so the default excecution logic is not changed.
> 
> Based on 2013 patch from Einar Lueck 
> 
> Signed-off-by: Ekaterina Tumanova 
> Reviewed-by: David Hildenbrand 
> Acked-by: Cornelia Huck 
> ---
>  block.c   | 12 
>  hw/block/block.c  | 25 +
>  hw/core/qdev-properties.c |  4 +++-
>  include/block/block.h |  1 +
>  include/block/block_int.h |  5 +
>  include/hw/block/block.h  |  2 ++
>  6 files changed, 48 insertions(+), 1 deletion(-)

This should be implemented as part of BlockLimits and
bdrv_refresh_limits().


pgpD0tNo01f0e.pgp
Description: PGP signature


[Qemu-devel] [PATCH 2/4] blocksize: support auto-sensing of blocksizes

2014-07-29 Thread Ekaterina Tumanova
The block device model does not impose fixed block sizes for
access to backing devices. This patch introduces support for
auto lookup of the block sizes of the backing block device.

To achieve this, a new function blkconf_blocksizes is
implemented. This function tries to get values
from the block driver. If this does not work 512 is used,
so the default excecution logic is not changed.

Based on 2013 patch from Einar Lueck 

Signed-off-by: Ekaterina Tumanova 
Reviewed-by: David Hildenbrand 
Acked-by: Cornelia Huck 
---
 block.c   | 12 
 hw/block/block.c  | 25 +
 hw/core/qdev-properties.c |  4 +++-
 include/block/block.h |  1 +
 include/block/block_int.h |  5 +
 include/hw/block/block.h  |  2 ++
 6 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 8cf519b..67de6e9 100644
--- a/block.c
+++ b/block.c
@@ -552,6 +552,18 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error 
**errp)
 }
 }
 
+int bdrv_probe_blocksizes(BlockDriverState *bs)
+{
+BlockDriver *drv = bs->drv;
+
+assert(drv != NULL);
+if (drv->bdrv_probe_blocksizes) {
+return drv->bdrv_probe_blocksizes(bs);
+}
+
+return -1;
+}
+
 /*
  * Create a uniquely-named empty temporary file.
  * Return 0 upon success, otherwise a negative errno value.
diff --git a/hw/block/block.c b/hw/block/block.c
index 33dd3f3..29a0227 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -10,6 +10,10 @@
 #include "sysemu/blockdev.h"
 #include "hw/block/block.h"
 #include "qemu/error-report.h"
+#include "block/block_int.h"
+#ifdef __linux__
+#include 
+#endif
 
 void blkconf_serial(BlockConf *conf, char **serial)
 {
@@ -22,6 +26,27 @@ void blkconf_serial(BlockConf *conf, char **serial)
 }
 }
 
+void blkconf_blocksizes(BlockConf *conf)
+{
+BlockDriverState *bs = conf->bs;
+
+/* default values as a basis - if probing fails */
+conf->physical_block_size = BLOCK_PROPERTY_STD_BLKSIZE;
+conf->logical_block_size = BLOCK_PROPERTY_STD_BLKSIZE;
+if (bdrv_probe_blocksizes(conf->bs) < 0) {
+return;
+}
+if (bs->logical_block_size) {
+conf->logical_block_size = (uint16_t)(bs->logical_block_size);
+}
+if (bs->physical_block_size) {
+conf->physical_block_size = (uint16_t)(bs->physical_block_size);
+} else if (conf->logical_block_size) {
+/* if driver sets no physical size, try to use logical size */
+conf->physical_block_size = conf->logical_block_size;
+}
+}
+
 int blkconf_geometry(BlockConf *conf, int *ptrans,
  unsigned cyls_max, unsigned heads_max, unsigned secs_max)
 {
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3d12560..49fb1e3 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -579,7 +579,9 @@ static void set_blocksize(Object *obj, Visitor *v, void 
*opaque,
 error_propagate(errp, local_err);
 return;
 }
-if (value < min || value > max) {
+
+/* value == 0 indicates that block size should be sensed later on */
+if ((value < min || value > max) && value > 0) {
 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
   dev->id?:"", name, (int64_t)value, min, max);
 return;
diff --git a/include/block/block.h b/include/block/block.h
index f08471d..43af424 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -583,6 +583,7 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs);
  * the old #AioContext is not executing.
  */
 void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context);
+int bdrv_probe_blocksizes(BlockDriverState *bs);
 
 void bdrv_io_plug(BlockDriverState *bs);
 void bdrv_io_unplug(BlockDriverState *bs);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 7b541a0..572e954 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -266,6 +266,8 @@ struct BlockDriver {
 void (*bdrv_io_unplug)(BlockDriverState *bs);
 void (*bdrv_flush_io_queue)(BlockDriverState *bs);
 
+int (*bdrv_probe_blocksizes)(BlockDriverState *bs);
+
 QLIST_ENTRY(BlockDriver) list;
 };
 
@@ -360,6 +362,9 @@ struct BlockDriverState {
 /* the block size for which the guest device expects atomicity */
 int guest_block_size;
 
+unsigned int physical_block_size;
+unsigned int logical_block_size;
+
 /* do we need to tell the quest if we have a volatile write cache? */
 int enable_write_cache;
 
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 7c3d6c8..7a0092e 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -40,6 +40,7 @@ static inline unsigned int get_physical_block_exp(BlockConf 
*conf)
 return exp;
 }
 
+#define BLOCK_PROPERTY_STD_BLKSIZE 512
 #define DEFINE_BLOCK_PROPERTIES(_state, _conf)  \
 DEFINE_PROP_DRIVE("drive", _state, _conf.bs),   \
 DEFINE_PROP