This function separates filling the BlockLimits from bdrv_open(), which
allows it to call it from other operations which may change the limits
(e.g. modifications to the backing file chain or bdrv_reopen)
Signed-off-by: Kevin Wolf kw...@redhat.com
---
block.c | 19 +++
block/iscsi.c | 46 +-
block/qcow2.c | 11 ++-
block/qed.c | 11 ++-
block/vmdk.c | 22 ++
include/block/block_int.h | 2 ++
6 files changed, 88 insertions(+), 23 deletions(-)
diff --git a/block.c b/block.c
index 13f001a..3bbcad4 100644
--- a/block.c
+++ b/block.c
@@ -479,6 +479,19 @@ int bdrv_create_file(const char* filename,
QEMUOptionParameter *options,
return ret;
}
+static int bdrv_refresh_limits(BlockDriverState *bs)
+{
+BlockDriver *drv = bs-drv;
+
+memset(bs-bl, 0, sizeof(bs-bl));
+
+if (drv drv-bdrv_refresh_limits) {
+return drv-bdrv_refresh_limits(bs);
+}
+
+return 0;
+}
+
/*
* Create a uniquely-named empty temporary file.
* Return 0 upon success, otherwise a negative errno value.
@@ -833,6 +846,8 @@ static int bdrv_open_common(BlockDriverState *bs,
BlockDriverState *file,
goto free_and_fail;
}
+bdrv_refresh_limits(bs);
+
#ifndef _WIN32
if (bs-is_temporary) {
assert(bs-filename[0] != '\0');
@@ -1018,6 +1033,10 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict
*options, Error **errp)
}
pstrcpy(bs-backing_file, sizeof(bs-backing_file),
bs-backing_hd-file-filename);
+
+/* Recalculate the BlockLimits with the backing file */
+bdrv_refresh_limits(bs);
+
return 0;
}
diff --git a/block/iscsi.c b/block/iscsi.c
index 829d444..18bc093 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1443,23 +1443,6 @@ static int iscsi_open(BlockDriverState *bs, QDict
*options, int flags,
sizeof(struct scsi_inquiry_block_limits));
scsi_free_scsi_task(task);
task = NULL;
-
-if (iscsilun-bl.max_unmap 0x) {
-bs-bl.max_discard = sector_lun2qemu(iscsilun-bl.max_unmap,
- iscsilun);
-}
-bs-bl.discard_alignment = sector_lun2qemu(iscsilun-bl.opt_unmap_gran,
- iscsilun);
-
-if (iscsilun-bl.max_ws_len 0x) {
-bs-bl.max_write_zeroes = sector_lun2qemu(iscsilun-bl.max_ws_len,
- iscsilun);
-}
-bs-bl.write_zeroes_alignment =
sector_lun2qemu(iscsilun-bl.opt_unmap_gran,
-iscsilun);
-
-bs-bl.opt_transfer_length = sector_lun2qemu(iscsilun-bl.opt_xfer_len,
- iscsilun);
}
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
@@ -1504,6 +1487,34 @@ static void iscsi_close(BlockDriverState *bs)
memset(iscsilun, 0, sizeof(IscsiLun));
}
+static int iscsi_refresh_limits(BlockDriverState *bs)
+{
+IscsiLun *iscsilun = bs-opaque;
+
+/* We don't actually refresh here, but just return data queried in
+ * iscsi_open(): iscsi targets don't change their limits. */
+if (iscsilun-lbp.lbpu || iscsilun-lbp.lbpws) {
+if (iscsilun-bl.max_unmap 0x) {
+bs-bl.max_discard = sector_lun2qemu(iscsilun-bl.max_unmap,
+ iscsilun);
+}
+bs-bl.discard_alignment = sector_lun2qemu(iscsilun-bl.opt_unmap_gran,
+ iscsilun);
+
+if (iscsilun-bl.max_ws_len 0x) {
+bs-bl.max_write_zeroes = sector_lun2qemu(iscsilun-bl.max_ws_len,
+ iscsilun);
+}
+bs-bl.write_zeroes_alignment =
sector_lun2qemu(iscsilun-bl.opt_unmap_gran,
+iscsilun);
+
+bs-bl.opt_transfer_length = sector_lun2qemu(iscsilun-bl.opt_xfer_len,
+ iscsilun);
+}
+
+return 0;
+}
+
static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
{
IscsiLun *iscsilun = bs-opaque;
@@ -1616,6 +1627,7 @@ static BlockDriver bdrv_iscsi = {
.bdrv_getlength = iscsi_getlength,
.bdrv_get_info = iscsi_get_info,
.bdrv_truncate = iscsi_truncate,
+.bdrv_refresh_limits = iscsi_refresh_limits,
#if defined(LIBISCSI_FEATURE_IOVECTOR)
.bdrv_co_get_block_status = iscsi_co_get_block_status,
diff --git a/block/qcow2.c b/block/qcow2.c
index f29aa88..f40355c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -718,7 +718,6 @@ static int qcow2_open(BlockDriverState *bs, QDict *options,
int flags,
}
qemu_opts_del(opts);
-bs-bl.write_zeroes_alignment = s-cluster_sectors;
if