qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Ekaterina Tumanova
Subject: [Qemu-devel] [PATCH 2/4] blocksize: support auto-sensing of blocksizes
Date: Tue, 29 Jul 2014 14:27:17 +0200

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 <address@hidden>

Signed-off-by: Ekaterina Tumanova <address@hidden>
Reviewed-by: David Hildenbrand <address@hidden>
Acked-by: Cornelia Huck <address@hidden>
---
 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 <linux/fs.h>
+#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_BLOCKSIZE("logical_block_size", _state,                 \
@@ -60,6 +61,7 @@ static inline unsigned int get_physical_block_exp(BlockConf 
*conf)
 /* Configuration helpers */
 
 void blkconf_serial(BlockConf *conf, char **serial);
+void blkconf_blocksizes(BlockConf *conf);
 int blkconf_geometry(BlockConf *conf, int *trans,
                      unsigned cyls_max, unsigned heads_max, unsigned secs_max);
 
-- 
1.8.5.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]