BAT is written in the context of conventional operations over
the image inside bdrv_co_flush() when it calls
parallels_co_flush_to_os() callback. Thus we should not
modify BAT array directly, but call parallels_set_bat_entry()
helper and bdrv_co_flush() further on. After that there is no
need to manually write BAT and track its modification.
This makes code more generic and allows to split
parallels_set_bat_entry() for independent pieces.
Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
---
v2: Patch order was changed so the replacement is done in parallels_co_check.
Now we use a helper to set BAT entry and mark the block dirty.
v3: Fix commit message.
block/parallels.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/block/parallels.c b/block/parallels.c
index 7f68f3cbc9..6879ea4597 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -428,7 +428,6 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
int64_t size, prev_off, high_off;
int ret;
uint32_t i;
- bool flush_bat = false;
size = bdrv_getlength(bs->file->bs);
if (size < 0) {
@@ -467,9 +466,8 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
res->corruptions++;
if (fix & BDRV_FIX_ERRORS) {
prev_off = 0;
- s->bat_bitmap[i] = 0;
+ parallels_set_bat_entry(s, i, 0);
res->corruptions_fixed++;
- flush_bat = true;
continue;
}
}
@@ -485,15 +483,6 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
prev_off = off;
}
- ret = 0;
- if (flush_bat) {
- ret = bdrv_co_pwrite_sync(bs->file, 0, s->header_size, s->header, 0);
- if (ret < 0) {
- res->check_errors++;
- goto out;
- }
- }
-
res->image_end_offset = high_off + s->cluster_size;
if (size > res->image_end_offset) {
int64_t count;
@@ -522,6 +511,12 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
out:
qemu_co_mutex_unlock(&s->lock);
+
+ ret = bdrv_co_flush(bs);
+ if (ret < 0) {
+ res->check_errors++;
+ }
+
return ret;
}
--
2.34.1
On 8/15/22 12:02, Alexander Ivanov wrote:
> BAT is written in the context of conventional operations over
> the image inside bdrv_co_flush() when it calls
> parallels_co_flush_to_os() callback. Thus we should not
> modify BAT array directly, but call parallels_set_bat_entry()
> helper and bdrv_co_flush() further on. After that there is no
> need to manually write BAT and track its modification.
>
> This makes code more generic and allows to split
> parallels_set_bat_entry() for independent pieces.
>
> Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
> ---
> v2: Patch order was changed so the replacement is done in parallels_co_check.
> Now we use a helper to set BAT entry and mark the block dirty.
> v3: Fix commit message.
>
> block/parallels.c | 19 +++++++------------
> 1 file changed, 7 insertions(+), 12 deletions(-)
>
> diff --git a/block/parallels.c b/block/parallels.c
> index 7f68f3cbc9..6879ea4597 100644
> --- a/block/parallels.c
> +++ b/block/parallels.c
> @@ -428,7 +428,6 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
> int64_t size, prev_off, high_off;
> int ret;
> uint32_t i;
> - bool flush_bat = false;
>
> size = bdrv_getlength(bs->file->bs);
> if (size < 0) {
> @@ -467,9 +466,8 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
> res->corruptions++;
> if (fix & BDRV_FIX_ERRORS) {
> prev_off = 0;
> - s->bat_bitmap[i] = 0;
> + parallels_set_bat_entry(s, i, 0);
> res->corruptions_fixed++;
> - flush_bat = true;
> continue;
> }
> }
> @@ -485,15 +483,6 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
> prev_off = off;
> }
>
> - ret = 0;
> - if (flush_bat) {
> - ret = bdrv_co_pwrite_sync(bs->file, 0, s->header_size, s->header, 0);
> - if (ret < 0) {
> - res->check_errors++;
> - goto out;
> - }
> - }
> -
> res->image_end_offset = high_off + s->cluster_size;
> if (size > res->image_end_offset) {
> int64_t count;
> @@ -522,6 +511,12 @@ static int coroutine_fn parallels_co_check(BlockDriverState *bs,
>
> out:
> qemu_co_mutex_unlock(&s->lock);
> +
> + ret = bdrv_co_flush(bs);
Oops that's wrong. Here we probably rewrite previous error of bdrv_truncate stored in ret variable.
> + if (ret < 0) {
> + res->check_errors++;
> + }
> +
> return ret;
> }
>
--
Best regards,
Vladimir
On 17.08.2022 21:48, Vladimir Sementsov-Ogievskiy wrote:
> On 8/15/22 12:02, Alexander Ivanov wrote:
>> BAT is written in the context of conventional operations over
>> the image inside bdrv_co_flush() when it calls
>> parallels_co_flush_to_os() callback. Thus we should not
>> modify BAT array directly, but call parallels_set_bat_entry()
>> helper and bdrv_co_flush() further on. After that there is no
>> need to manually write BAT and track its modification.
>>
>> This makes code more generic and allows to split
>> parallels_set_bat_entry() for independent pieces.
>>
>> Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
>> ---
>> v2: Patch order was changed so the replacement is done in
>> parallels_co_check.
>> Now we use a helper to set BAT entry and mark the block dirty.
>> v3: Fix commit message.
>>
>> block/parallels.c | 19 +++++++------------
>> 1 file changed, 7 insertions(+), 12 deletions(-)
>>
>> diff --git a/block/parallels.c b/block/parallels.c
>> index 7f68f3cbc9..6879ea4597 100644
>> --- a/block/parallels.c
>> +++ b/block/parallels.c
>> @@ -428,7 +428,6 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> int64_t size, prev_off, high_off;
>> int ret;
>> uint32_t i;
>> - bool flush_bat = false;
>> size = bdrv_getlength(bs->file->bs);
>> if (size < 0) {
>> @@ -467,9 +466,8 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> res->corruptions++;
>> if (fix & BDRV_FIX_ERRORS) {
>> prev_off = 0;
>> - s->bat_bitmap[i] = 0;
>> + parallels_set_bat_entry(s, i, 0);
>> res->corruptions_fixed++;
>> - flush_bat = true;
>> continue;
>> }
>> }
>> @@ -485,15 +483,6 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> prev_off = off;
>> }
>> - ret = 0;
>> - if (flush_bat) {
>> - ret = bdrv_co_pwrite_sync(bs->file, 0, s->header_size,
>> s->header, 0);
>> - if (ret < 0) {
>> - res->check_errors++;
>> - goto out;
>> - }
>> - }
>> -
>> res->image_end_offset = high_off + s->cluster_size;
>> if (size > res->image_end_offset) {
>> int64_t count;
>> @@ -522,6 +511,12 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> out:
>> qemu_co_mutex_unlock(&s->lock);
>> +
>> + ret = bdrv_co_flush(bs);
>
> Oops that's wrong. Here we probably rewrite previous error of
> bdrv_truncate stored in ret variable.
Good point!
As you said in 8/8, now it doesn't matter, but I'll fix it for the patch
correctness.
>
>> + if (ret < 0) {
>> + res->check_errors++;
>> + }
>> +
>> return ret;
>> }
>
>
On 17.08.2022 21:48, Vladimir Sementsov-Ogievskiy wrote:
> On 8/15/22 12:02, Alexander Ivanov wrote:
>> BAT is written in the context of conventional operations over
>> the image inside bdrv_co_flush() when it calls
>> parallels_co_flush_to_os() callback. Thus we should not
>> modify BAT array directly, but call parallels_set_bat_entry()
>> helper and bdrv_co_flush() further on. After that there is no
>> need to manually write BAT and track its modification.
>>
>> This makes code more generic and allows to split
>> parallels_set_bat_entry() for independent pieces.
>>
>> Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
>> ---
>> v2: Patch order was changed so the replacement is done in
>> parallels_co_check.
>> Now we use a helper to set BAT entry and mark the block dirty.
>> v3: Fix commit message.
>>
>> block/parallels.c | 19 +++++++------------
>> 1 file changed, 7 insertions(+), 12 deletions(-)
>>
>> diff --git a/block/parallels.c b/block/parallels.c
>> index 7f68f3cbc9..6879ea4597 100644
>> --- a/block/parallels.c
>> +++ b/block/parallels.c
>> @@ -428,7 +428,6 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> int64_t size, prev_off, high_off;
>> int ret;
>> uint32_t i;
>> - bool flush_bat = false;
>> size = bdrv_getlength(bs->file->bs);
>> if (size < 0) {
>> @@ -467,9 +466,8 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> res->corruptions++;
>> if (fix & BDRV_FIX_ERRORS) {
>> prev_off = 0;
>> - s->bat_bitmap[i] = 0;
>> + parallels_set_bat_entry(s, i, 0);
>> res->corruptions_fixed++;
>> - flush_bat = true;
>> continue;
>> }
>> }
>> @@ -485,15 +483,6 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> prev_off = off;
>> }
>> - ret = 0;
>> - if (flush_bat) {
>> - ret = bdrv_co_pwrite_sync(bs->file, 0, s->header_size,
>> s->header, 0);
>> - if (ret < 0) {
>> - res->check_errors++;
>> - goto out;
>> - }
>> - }
>> -
>> res->image_end_offset = high_off + s->cluster_size;
>> if (size > res->image_end_offset) {
>> int64_t count;
>> @@ -522,6 +511,12 @@ static int coroutine_fn
>> parallels_co_check(BlockDriverState *bs,
>> out:
>> qemu_co_mutex_unlock(&s->lock);
>> +
>> + ret = bdrv_co_flush(bs);
>
> Oops that's wrong. Here we probably rewrite previous error of
> bdrv_truncate stored in ret variable.
>
You absolutely right, we have missed this point.
Good catch!
>> + if (ret < 0) {
>> + res->check_errors++;
>> + }
>> +
>> return ret;
>> }
>
>
© 2016 - 2026 Red Hat, Inc.