* [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images
@ 2014-08-16 18:54 Max Reitz
2014-08-16 18:54 ` [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file Max Reitz
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Max Reitz @ 2014-08-16 18:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
Patch 2:
The bdrv_is_allocated() functions may return a number of zero sectors
e.g. if a sector beyond the image end has been queried. Respect this
case in qemu-io's map implementation so it doesn't run into an infinite
loop (https://bugs.launchpad.net/qemu/+bug/1356969).
Patch 1:
In that bug report, bdrv_co_get_block_status() fell through to the
underlying file to get additional information (whether the sectors are
zeroed). However, the offset reported by the image format (qcow2) was
beyond the size of the underlying file and so this second query returned
only zero clusters which replaced the actual number of sectors queried
in the "formatted" (on qcow2 level) image. But because errors from this
second call are ignored, the number of sector queried successfully
should be ignored as well, which makes qemu-io -c map actually work for
that bug report.
Patch 3 adds a test for patch 1; I could not conceive a test for patch 2
which patch 1 would not already catch, but patch 2 should be simple
enough not to require a test anyway.
Thanks to patch 3, this series depends on my previous series
"[PATCH v10 00/14] qemu-img: Implement commit like QMP"
(strictly speaking only on patch 11 of that series which adds
_filter_qemu_img_map() to tests/qemu-iotests/common.filter).
Max Reitz (3):
block: Ignore allocation size in underlying file
qemu-io: Respect early image end for map
iotests: Add test for map commands
block.c | 6 +++--
qemu-io-cmds.c | 5 +++-
tests/qemu-iotests/102 | 64 ++++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/102.out | 11 ++++++++
tests/qemu-iotests/group | 1 +
5 files changed, 84 insertions(+), 3 deletions(-)
create mode 100755 tests/qemu-iotests/102
create mode 100644 tests/qemu-iotests/102.out
--
2.0.4
^ permalink raw reply [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file
2014-08-16 18:54 [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
@ 2014-08-16 18:54 ` Max Reitz
2014-10-08 21:29 ` Eric Blake
2014-10-10 11:50 ` Benoît Canet
2014-08-16 18:54 ` [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map Max Reitz
` (2 subsequent siblings)
3 siblings, 2 replies; 15+ messages in thread
From: Max Reitz @ 2014-08-16 18:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
When falling through to the underlying file in
bdrv_co_get_block_status(), do not let the number of sectors for which
information could be obtained be overwritten.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
block.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block.c b/block.c
index 3e252a2..c922664 100644
--- a/block.c
+++ b/block.c
@@ -3991,9 +3991,11 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
if (bs->file &&
(ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
(ret & BDRV_BLOCK_OFFSET_VALID)) {
+ int backing_pnum;
+
ret2 = bdrv_co_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
- *pnum, pnum);
- if (ret2 >= 0) {
+ *pnum, &backing_pnum);
+ if (ret2 >= 0 && backing_pnum >= *pnum) {
/* Ignore errors. This is just providing extra information, it
* is useful but not necessary.
*/
--
2.0.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map
2014-08-16 18:54 [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
2014-08-16 18:54 ` [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file Max Reitz
@ 2014-08-16 18:54 ` Max Reitz
2014-10-09 4:17 ` Eric Blake
` (2 more replies)
2014-08-16 18:54 ` [Qemu-devel] [PATCH 3/3] iotests: Add test for map commands Max Reitz
2014-10-08 19:32 ` [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
3 siblings, 3 replies; 15+ messages in thread
From: Max Reitz @ 2014-08-16 18:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
bdrv_is_allocated() may report zero clusters which most probably means
the image (file) is shorter than expected. Respect this case in order to
avoid an infinite loop.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
qemu-io-cmds.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index c503fc6..860b834 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1909,7 +1909,7 @@ static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
num_checked = MIN(nb_sectors, INT_MAX);
ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
- if (ret == firstret) {
+ if (ret == firstret && num) {
*pnum += num;
} else {
break;
@@ -1936,6 +1936,9 @@ static int map_f(BlockDriverState *bs, int argc, char **argv)
if (ret < 0) {
error_report("Failed to get allocation status: %s", strerror(-ret));
return 0;
+ } else if (!num) {
+ error_report("Unexpected end of image");
+ return 0;
}
retstr = ret ? " allocated" : "not allocated";
--
2.0.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [Qemu-devel] [PATCH 3/3] iotests: Add test for map commands
2014-08-16 18:54 [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
2014-08-16 18:54 ` [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file Max Reitz
2014-08-16 18:54 ` [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map Max Reitz
@ 2014-08-16 18:54 ` Max Reitz
2014-10-09 4:18 ` Eric Blake
2014-10-08 19:32 ` [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
3 siblings, 1 reply; 15+ messages in thread
From: Max Reitz @ 2014-08-16 18:54 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
Add a test for qemu-img map and qemu-io -c map on truncated files.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
tests/qemu-iotests/102 | 64 ++++++++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/102.out | 11 ++++++++
tests/qemu-iotests/group | 1 +
3 files changed, 76 insertions(+)
create mode 100755 tests/qemu-iotests/102
create mode 100644 tests/qemu-iotests/102.out
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
new file mode 100755
index 0000000..7ac46ef
--- /dev/null
+++ b/tests/qemu-iotests/102
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Test case for qemu-io -c map and qemu-img map
+#
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=mreitz@redhat.com
+
+seq=$(basename $0)
+echo "QA output created by $seq"
+
+here=$PWD
+tmp=/tmp/$$
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+IMG_SIZE=64K
+
+echo
+echo '=== Testing map command on truncated image ==='
+echo
+
+_make_test_img $IMG_SIZE
+# Create cluster
+$QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
+# Remove data cluster from image (first cluster: image header, second: reftable,
+# third: refblock, fourth: L1 table, fifth: L2 table)
+truncate -s $((5 * 64 * 1024)) "$TEST_IMG"
+
+$QEMU_IO -c map "$TEST_IMG"
+$QEMU_IMG map "$TEST_IMG" | _filter_qemu_img_map
+
+# success, all done
+echo '*** done'
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/102.out b/tests/qemu-iotests/102.out
new file mode 100644
index 0000000..af3a2a6
--- /dev/null
+++ b/tests/qemu-iotests/102.out
@@ -0,0 +1,11 @@
+QA output created by 102
+
+=== Testing map command on truncated image ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
+wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+[ 0] 128/ 128 sectors allocated at offset 0 bytes (1)
+Offset Length File
+0 0x10000 TEST_DIR/t.IMGFMT
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index dfbd0ed..b8f7c39 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -102,3 +102,4 @@
095 rw auto quick
097 rw auto backing
098 rw auto backing quick
+102 rw auto quick
--
2.0.4
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images
2014-08-16 18:54 [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
` (2 preceding siblings ...)
2014-08-16 18:54 ` [Qemu-devel] [PATCH 3/3] iotests: Add test for map commands Max Reitz
@ 2014-10-08 19:32 ` Max Reitz
3 siblings, 0 replies; 15+ messages in thread
From: Max Reitz @ 2014-10-08 19:32 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Paolo Bonzini, Fam Zheng, Benoît Canet,
Stefan Hajnoczi
On 16.08.2014 20:54, Max Reitz wrote:
> Patch 2:
> The bdrv_is_allocated() functions may return a number of zero sectors
> e.g. if a sector beyond the image end has been queried. Respect this
> case in qemu-io's map implementation so it doesn't run into an infinite
> loop (https://bugs.launchpad.net/qemu/+bug/1356969).
>
> Patch 1:
> In that bug report, bdrv_co_get_block_status() fell through to the
> underlying file to get additional information (whether the sectors are
> zeroed). However, the offset reported by the image format (qcow2) was
> beyond the size of the underlying file and so this second query returned
> only zero clusters which replaced the actual number of sectors queried
> in the "formatted" (on qcow2 level) image. But because errors from this
> second call are ignored, the number of sector queried successfully
> should be ignored as well, which makes qemu-io -c map actually work for
> that bug report.
>
> Patch 3 adds a test for patch 1; I could not conceive a test for patch 2
> which patch 1 would not already catch, but patch 2 should be simple
> enough not to require a test anyway.
>
> Thanks to patch 3, this series depends on my previous series
> "[PATCH v10 00/14] qemu-img: Implement commit like QMP"
> (strictly speaking only on patch 11 of that series which adds
> _filter_qemu_img_map() to tests/qemu-iotests/common.filter).
>
>
> Max Reitz (3):
> block: Ignore allocation size in underlying file
> qemu-io: Respect early image end for map
> iotests: Add test for map commands
>
> block.c | 6 +++--
> qemu-io-cmds.c | 5 +++-
> tests/qemu-iotests/102 | 64 ++++++++++++++++++++++++++++++++++++++++++++++
> tests/qemu-iotests/102.out | 11 ++++++++
> tests/qemu-iotests/group | 1 +
> 5 files changed, 84 insertions(+), 3 deletions(-)
> create mode 100755 tests/qemu-iotests/102
> create mode 100644 tests/qemu-iotests/102.out
>
Ping.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file
2014-08-16 18:54 ` [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file Max Reitz
@ 2014-10-08 21:29 ` Eric Blake
2014-10-10 11:50 ` Benoît Canet
1 sibling, 0 replies; 15+ messages in thread
From: Eric Blake @ 2014-10-08 21:29 UTC (permalink / raw)
To: Max Reitz, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi
[-- Attachment #1: Type: text/plain, Size: 509 bytes --]
On 08/16/2014 12:54 PM, Max Reitz wrote:
> When falling through to the underlying file in
> bdrv_co_get_block_status(), do not let the number of sectors for which
> information could be obtained be overwritten.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map
2014-08-16 18:54 ` [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map Max Reitz
@ 2014-10-09 4:17 ` Eric Blake
2014-10-10 12:03 ` Benoît Canet
2014-10-11 18:47 ` Benoît Canet
2 siblings, 0 replies; 15+ messages in thread
From: Eric Blake @ 2014-10-09 4:17 UTC (permalink / raw)
To: Max Reitz, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi
[-- Attachment #1: Type: text/plain, Size: 520 bytes --]
On 08/16/2014 12:54 PM, Max Reitz wrote:
> bdrv_is_allocated() may report zero clusters which most probably means
> the image (file) is shorter than expected. Respect this case in order to
> avoid an infinite loop.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> qemu-io-cmds.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] iotests: Add test for map commands
2014-08-16 18:54 ` [Qemu-devel] [PATCH 3/3] iotests: Add test for map commands Max Reitz
@ 2014-10-09 4:18 ` Eric Blake
0 siblings, 0 replies; 15+ messages in thread
From: Eric Blake @ 2014-10-09 4:18 UTC (permalink / raw)
To: Max Reitz, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi
[-- Attachment #1: Type: text/plain, Size: 633 bytes --]
On 08/16/2014 12:54 PM, Max Reitz wrote:
> Add a test for qemu-img map and qemu-io -c map on truncated files.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> tests/qemu-iotests/102 | 64 ++++++++++++++++++++++++++++++++++++++++++++++
> tests/qemu-iotests/102.out | 11 ++++++++
> tests/qemu-iotests/group | 1 +
> 3 files changed, 76 insertions(+)
> create mode 100755 tests/qemu-iotests/102
> create mode 100644 tests/qemu-iotests/102.out
>
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 539 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file
2014-08-16 18:54 ` [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file Max Reitz
2014-10-08 21:29 ` Eric Blake
@ 2014-10-10 11:50 ` Benoît Canet
2014-10-11 9:44 ` Max Reitz
1 sibling, 1 reply; 15+ messages in thread
From: Benoît Canet @ 2014-10-10 11:50 UTC (permalink / raw)
To: Max Reitz; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
The Saturday 16 Aug 2014 à 20:54:16 (+0200), Max Reitz wrote :
> When falling through to the underlying file in
> bdrv_co_get_block_status(), do not let the number of sectors for which
> information could be obtained be overwritten.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/block.c b/block.c
> index 3e252a2..c922664 100644
> --- a/block.c
> +++ b/block.c
> @@ -3991,9 +3991,11 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
> if (bs->file &&
> (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
> (ret & BDRV_BLOCK_OFFSET_VALID)) {
> + int backing_pnum;
> +
> ret2 = bdrv_co_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
> - *pnum, pnum);
> - if (ret2 >= 0) {
> + *pnum, &backing_pnum);
> + if (ret2 >= 0 && backing_pnum >= *pnum) {
About backing_pnum >= *pnum.
The documentation of bdrv_co_get_block_status says:
* 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
* beyond the end of the disk image it will be clamped.
*/
static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
int64_t sector_num,
int nb_sectors, int *pnum)
So clearly after the bdrv_co_get_block_status *pnum >= backing_pnum.
This means that backing_pnum > *pnum will never happen.
I think either this test is wrong or the doc is wrong.
Best regards
Benoît
> /* Ignore errors. This is just providing extra information, it
> * is useful but not necessary.
> */
> --
> 2.0.4
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map
2014-08-16 18:54 ` [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map Max Reitz
2014-10-09 4:17 ` Eric Blake
@ 2014-10-10 12:03 ` Benoît Canet
2014-10-11 9:53 ` Max Reitz
2014-10-11 18:47 ` Benoît Canet
2 siblings, 1 reply; 15+ messages in thread
From: Benoît Canet @ 2014-10-10 12:03 UTC (permalink / raw)
To: Max Reitz; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
> + } else if (!num) {
> + error_report("Unexpected end of image");
> + return 0;
I think this test can miss some case of Unexpected end of image.
For example supose that in map_is_allocated the first bdrv_is_allocated
actually succeed then *pnum = num. Then the bottom loop has exit on failure
and the function return.
in map_f &num is map_is_allocated *pnum so map_f's num != 0 and this very test
fails to see the unexpected end of image error.
Best regards
Benoît
> }
>
> retstr = ret ? " allocated" : "not allocated";
> --
> 2.0.4
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file
2014-10-10 11:50 ` Benoît Canet
@ 2014-10-11 9:44 ` Max Reitz
2014-10-11 18:48 ` Benoît Canet
0 siblings, 1 reply; 15+ messages in thread
From: Max Reitz @ 2014-10-11 9:44 UTC (permalink / raw)
To: Benoît Canet; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
Am 10.10.2014 um 13:50 schrieb Benoît Canet:
> The Saturday 16 Aug 2014 à 20:54:16 (+0200), Max Reitz wrote :
>> When falling through to the underlying file in
>> bdrv_co_get_block_status(), do not let the number of sectors for which
>> information could be obtained be overwritten.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>> block.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/block.c b/block.c
>> index 3e252a2..c922664 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -3991,9 +3991,11 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
>> if (bs->file &&
>> (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
>> (ret & BDRV_BLOCK_OFFSET_VALID)) {
>> + int backing_pnum;
>> +
>> ret2 = bdrv_co_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
>> - *pnum, pnum);
>> - if (ret2 >= 0) {
>> + *pnum, &backing_pnum);
>> + if (ret2 >= 0 && backing_pnum >= *pnum) {
> About backing_pnum >= *pnum.
>
> The documentation of bdrv_co_get_block_status says:
>
> * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
> * beyond the end of the disk image it will be clamped.
> */
> static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
> int64_t sector_num,
> int nb_sectors, int *pnum)
>
> So clearly after the bdrv_co_get_block_status *pnum >= backing_pnum.
>
> This means that backing_pnum > *pnum will never happen.
>
> I think either this test is wrong or the doc is wrong.
Thank you for confusing me, I had to think quite a while about this. *g*
The condition is not for error checking. If it was, it would be the
wrong order (the condition should be true on success, that's why it's
"ret2 >= 0" and not "ret2 < 0", so it should then be "backing_pnum <=
*pnum"). So what this is testing is whether all sectors in the
underlying file in the queried range are read as zero. But if
"backing_pnum < *pnum" that is not the case, some clusters are not zero.
So we may not set the zero flag if backing_pnum < *pnum; or as it reads
in the code, we may only set it if backing_pnum >= *pnum. This is not
about whether *pnum > backing_pnum, but more about whether backing_pnum
== *pnum (but >= would be fine, too, if bdrv_co_get_block_status()
supported it, so that's why I wrote it that way).
However, I'm starting to think about whether it would be better, for the
backing_pnum < *pnum case, not to not set the zero flag, but rather
simply set *pnum = backing_pnum. And this in turn would be pretty
equivalent to just omitting this patch, because:
If we get to this point where we query the underlying file and it
returns a certain number of sectors is zero; then we therefore want to
set *pnum = backing_pnum (both if backing_pnum < *pnum and if
backing_pnum == *pnum; backing_pnum > *pnum cannot happen, as you
pointed out). On the other hand, if the sectors are not reported to be
zero, but backing_pnum < *pnum, we want to shorten *pnum accordingly as
well because this may indicate that after another backing_pnum sectors,
we arrive at a hole in the file.
There is only one point I can imagine where it makes sense not to let
backing_pnum overwrite *pnum: And that's if bdrv_co_get_block_status()
reported BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID with an offset beyond
the EOF. I think this might actually happen with qcow2, if one cluster
simply lies beyond the EOF (which is perfectly valid). So I conclude
that this patch has its use after all but needs to be modified so that
backing_pnum always overwrites *pnum; except for when backing_pnum is
zero (which should only happen at or after the EOF) in which case the
zero flag should be set and *pnum should be left as it was.
And now in all honesty: Thanks for confusing me, I guess I can think
better when I'm confused. :-)
Max
> Best regards
>
> Benoît
>
>
>> /* Ignore errors. This is just providing extra information, it
>> * is useful but not necessary.
>> */
>> --
>> 2.0.4
>>
>>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map
2014-10-10 12:03 ` Benoît Canet
@ 2014-10-11 9:53 ` Max Reitz
2014-10-11 18:46 ` Benoît Canet
0 siblings, 1 reply; 15+ messages in thread
From: Max Reitz @ 2014-10-11 9:53 UTC (permalink / raw)
To: Benoît Canet; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
Am 10.10.2014 um 14:03 schrieb Benoît Canet:
>> + } else if (!num) {
>> + error_report("Unexpected end of image");
>> + return 0;
> I think this test can miss some case of Unexpected end of image.
>
> For example supose that in map_is_allocated the first bdrv_is_allocated
> actually succeed then *pnum = num. Then the bottom loop has exit on failure
> and the function return.
>
> in map_f &num is map_is_allocated *pnum so map_f's num != 0 and this very test
> fails to see the unexpected end of image error.
num != 0 because some sectors where successfully queried. In my opinion,
we should print the information about them we have. Then, the do-while
loop is repeated; and this time, map_is_allocated() either again returns
num > 0 (for whatever reason, but I'd be fine with it) or, more
probably, it'll be num == 0 this time. So the error is not missed, it's
just printed one iteration later.
Max
> Best regards
>
> Benoît
>
>> }
>>
>> retstr = ret ? " allocated" : "not allocated";
>> --
>> 2.0.4
>>
>>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map
2014-10-11 9:53 ` Max Reitz
@ 2014-10-11 18:46 ` Benoît Canet
0 siblings, 0 replies; 15+ messages in thread
From: Benoît Canet @ 2014-10-11 18:46 UTC (permalink / raw)
To: Max Reitz; +Cc: Benoît Canet, Kevin Wolf, qemu-devel, Stefan Hajnoczi
The Saturday 11 Oct 2014 à 11:53:40 (+0200), Max Reitz wrote :
> Am 10.10.2014 um 14:03 schrieb Benoît Canet:
> >>+ } else if (!num) {
> >>+ error_report("Unexpected end of image");
> >>+ return 0;
> >I think this test can miss some case of Unexpected end of image.
> >
> >For example supose that in map_is_allocated the first bdrv_is_allocated
> >actually succeed then *pnum = num. Then the bottom loop has exit on failure
> >and the function return.
> >
> >in map_f &num is map_is_allocated *pnum so map_f's num != 0 and this very test
> >fails to see the unexpected end of image error.
>
> num != 0 because some sectors where successfully queried. In my opinion, we
> should print the information about them we have. Then, the do-while loop is
> repeated; and this time, map_is_allocated() either again returns num > 0
> (for whatever reason, but I'd be fine with it) or, more probably, it'll be
> num == 0 this time. So the error is not missed, it's just printed one
> iteration later.
Ok that make sense.
Best regards
Benoît
>
> Max
>
> >Best regards
> >
> >Benoît
> >
> >> }
> >> retstr = ret ? " allocated" : "not allocated";
> >>--
> >>2.0.4
> >>
> >>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map
2014-08-16 18:54 ` [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map Max Reitz
2014-10-09 4:17 ` Eric Blake
2014-10-10 12:03 ` Benoît Canet
@ 2014-10-11 18:47 ` Benoît Canet
2 siblings, 0 replies; 15+ messages in thread
From: Benoît Canet @ 2014-10-11 18:47 UTC (permalink / raw)
To: Max Reitz; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
The Saturday 16 Aug 2014 à 20:54:17 (+0200), Max Reitz wrote :
> bdrv_is_allocated() may report zero clusters which most probably means
> the image (file) is shorter than expected. Respect this case in order to
> avoid an infinite loop.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> qemu-io-cmds.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
> index c503fc6..860b834 100644
> --- a/qemu-io-cmds.c
> +++ b/qemu-io-cmds.c
> @@ -1909,7 +1909,7 @@ static int map_is_allocated(BlockDriverState *bs, int64_t sector_num,
>
> num_checked = MIN(nb_sectors, INT_MAX);
> ret = bdrv_is_allocated(bs, sector_num, num_checked, &num);
> - if (ret == firstret) {
> + if (ret == firstret && num) {
> *pnum += num;
> } else {
> break;
> @@ -1936,6 +1936,9 @@ static int map_f(BlockDriverState *bs, int argc, char **argv)
> if (ret < 0) {
> error_report("Failed to get allocation status: %s", strerror(-ret));
> return 0;
> + } else if (!num) {
> + error_report("Unexpected end of image");
> + return 0;
> }
>
> retstr = ret ? " allocated" : "not allocated";
> --
> 2.0.4
>
>
Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file
2014-10-11 9:44 ` Max Reitz
@ 2014-10-11 18:48 ` Benoît Canet
0 siblings, 0 replies; 15+ messages in thread
From: Benoît Canet @ 2014-10-11 18:48 UTC (permalink / raw)
To: Max Reitz; +Cc: Benoît Canet, Kevin Wolf, qemu-devel, Stefan Hajnoczi
The Saturday 11 Oct 2014 à 11:44:20 (+0200), Max Reitz wrote :
> Am 10.10.2014 um 13:50 schrieb Benoît Canet:
> >The Saturday 16 Aug 2014 à 20:54:16 (+0200), Max Reitz wrote :
> >>When falling through to the underlying file in
> >>bdrv_co_get_block_status(), do not let the number of sectors for which
> >>information could be obtained be overwritten.
> >>
> >>Signed-off-by: Max Reitz <mreitz@redhat.com>
> >>---
> >> block.c | 6 ++++--
> >> 1 file changed, 4 insertions(+), 2 deletions(-)
> >>
> >>diff --git a/block.c b/block.c
> >>index 3e252a2..c922664 100644
> >>--- a/block.c
> >>+++ b/block.c
> >>@@ -3991,9 +3991,11 @@ static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
> >> if (bs->file &&
> >> (ret & BDRV_BLOCK_DATA) && !(ret & BDRV_BLOCK_ZERO) &&
> >> (ret & BDRV_BLOCK_OFFSET_VALID)) {
> >>+ int backing_pnum;
> >>+
> >> ret2 = bdrv_co_get_block_status(bs->file, ret >> BDRV_SECTOR_BITS,
> >>- *pnum, pnum);
> >>- if (ret2 >= 0) {
> >>+ *pnum, &backing_pnum);
> >>+ if (ret2 >= 0 && backing_pnum >= *pnum) {
> >About backing_pnum >= *pnum.
> >
> >The documentation of bdrv_co_get_block_status says:
> >
> > * 'nb_sectors' is the max value 'pnum' should be set to. If nb_sectors goes
> > * beyond the end of the disk image it will be clamped.
> > */
> >static int64_t coroutine_fn bdrv_co_get_block_status(BlockDriverState *bs,
> > int64_t sector_num,
> > int nb_sectors, int *pnum)
> >
> >So clearly after the bdrv_co_get_block_status *pnum >= backing_pnum.
> >
> >This means that backing_pnum > *pnum will never happen.
> >
> >I think either this test is wrong or the doc is wrong.
>
> Thank you for confusing me, I had to think quite a while about this. *g*
>
> The condition is not for error checking. If it was, it would be the wrong
> order (the condition should be true on success, that's why it's "ret2 >= 0"
> and not "ret2 < 0", so it should then be "backing_pnum <= *pnum"). So what
> this is testing is whether all sectors in the underlying file in the queried
> range are read as zero. But if "backing_pnum < *pnum" that is not the case,
> some clusters are not zero. So we may not set the zero flag if backing_pnum
> < *pnum; or as it reads in the code, we may only set it if backing_pnum >=
> *pnum. This is not about whether *pnum > backing_pnum, but more about
> whether backing_pnum == *pnum (but >= would be fine, too, if
> bdrv_co_get_block_status() supported it, so that's why I wrote it that way).
>
> However, I'm starting to think about whether it would be better, for the
> backing_pnum < *pnum case, not to not set the zero flag, but rather simply
> set *pnum = backing_pnum. And this in turn would be pretty equivalent to
> just omitting this patch, because:
>
> If we get to this point where we query the underlying file and it returns a
> certain number of sectors is zero; then we therefore want to set *pnum =
> backing_pnum (both if backing_pnum < *pnum and if backing_pnum == *pnum;
> backing_pnum > *pnum cannot happen, as you pointed out). On the other hand,
> if the sectors are not reported to be zero, but backing_pnum < *pnum, we
> want to shorten *pnum accordingly as well because this may indicate that
> after another backing_pnum sectors, we arrive at a hole in the file.
>
> There is only one point I can imagine where it makes sense not to let
> backing_pnum overwrite *pnum: And that's if bdrv_co_get_block_status()
> reported BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID with an offset beyond the
> EOF. I think this might actually happen with qcow2, if one cluster simply
> lies beyond the EOF (which is perfectly valid). So I conclude that this
> patch has its use after all but needs to be modified so that backing_pnum
> always overwrites *pnum; except for when backing_pnum is zero (which should
> only happen at or after the EOF) in which case the zero flag should be set
> and *pnum should be left as it was.
>
> And now in all honesty: Thanks for confusing me, I guess I can think better
> when I'm confused. :-)
>
You better have killer english skills to sumarize this in a nice commit message :)
I'll read the next version.
Best regards
Benoît
> Max
>
> >Best regards
> >
> >Benoît
> >
> >
> >> /* Ignore errors. This is just providing extra information, it
> >> * is useful but not necessary.
> >> */
> >>--
> >>2.0.4
> >>
> >>
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2014-10-11 18:51 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-16 18:54 [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
2014-08-16 18:54 ` [Qemu-devel] [PATCH 1/3] block: Ignore allocation size in underlying file Max Reitz
2014-10-08 21:29 ` Eric Blake
2014-10-10 11:50 ` Benoît Canet
2014-10-11 9:44 ` Max Reitz
2014-10-11 18:48 ` Benoît Canet
2014-08-16 18:54 ` [Qemu-devel] [PATCH 2/3] qemu-io: Respect early image end for map Max Reitz
2014-10-09 4:17 ` Eric Blake
2014-10-10 12:03 ` Benoît Canet
2014-10-11 9:53 ` Max Reitz
2014-10-11 18:46 ` Benoît Canet
2014-10-11 18:47 ` Benoît Canet
2014-08-16 18:54 ` [Qemu-devel] [PATCH 3/3] iotests: Add test for map commands Max Reitz
2014-10-09 4:18 ` Eric Blake
2014-10-08 19:32 ` [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images Max Reitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).