* [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate
@ 2013-09-25 14:37 Max Reitz
2013-09-25 14:37 ` [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache Max Reitz
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Max Reitz @ 2013-09-25 14:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
Errors in l2_allocate should always go down the error path. If this path
is taken, the newly allocated L2 cluster is abandoned and should thus be
freed. The L2 table on the other hand should only be put back into the
cache if it was taken from it before.
Max Reitz (3):
qcow2: Don't put invalid L2 table into cache
qcow2: Free allocated L2 cluster on error
qcow2: Always use error path in l2_allocate
block/qcow2-cluster.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache
2013-09-25 14:37 [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Max Reitz
@ 2013-09-25 14:37 ` Max Reitz
2013-09-25 14:47 ` Benoît Canet
2013-09-25 14:37 ` [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error Max Reitz
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Max Reitz @ 2013-09-25 14:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
In l2_allocate, the fail path is executed if qcow2_cache_flush fails.
However, the L2 table has not yet been fetched from the L2 table cache.
The qcow2_cache_put in the fail path therefore basically gives an
undefined argument as the L2 table address (in this case).
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2-cluster.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 738ff73..f6d47c9 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -188,7 +188,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
{
BDRVQcowState *s = bs->opaque;
uint64_t old_l2_offset;
- uint64_t *l2_table;
+ uint64_t *l2_table = NULL;
int64_t l2_offset;
int ret;
@@ -265,7 +265,9 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
fail:
trace_qcow2_l2_allocate_done(bs, l1_index, ret);
- qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
+ if (l2_table != NULL) {
+ qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
+ }
s->l1_table[l1_index] = old_l2_offset;
return ret;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error
2013-09-25 14:37 [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Max Reitz
2013-09-25 14:37 ` [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache Max Reitz
@ 2013-09-25 14:37 ` Max Reitz
2013-09-25 14:50 ` Benoît Canet
2013-09-27 14:54 ` Kevin Wolf
2013-09-25 14:37 ` [Qemu-devel] [PATCH 3/3] qcow2: Always use error path in l2_allocate Max Reitz
2013-09-27 9:38 ` [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Kevin Wolf
3 siblings, 2 replies; 11+ messages in thread
From: Max Reitz @ 2013-09-25 14:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
If an error occurs in l2_allocate, the allocated (but unused) L2 cluster
should be freed.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2-cluster.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f6d47c9..1c3d3fc 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -269,6 +269,10 @@ fail:
qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
}
s->l1_table[l1_index] = old_l2_offset;
+ if (l2_offset > 0) {
+ qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),
+ QCOW2_DISCARD_ALWAYS);
+ }
return ret;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Qemu-devel] [PATCH 3/3] qcow2: Always use error path in l2_allocate
2013-09-25 14:37 [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Max Reitz
2013-09-25 14:37 ` [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache Max Reitz
2013-09-25 14:37 ` [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error Max Reitz
@ 2013-09-25 14:37 ` Max Reitz
2013-09-25 14:56 ` Benoît Canet
2013-09-27 9:38 ` [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Kevin Wolf
3 siblings, 1 reply; 11+ messages in thread
From: Max Reitz @ 2013-09-25 14:37 UTC (permalink / raw)
To: qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi, Max Reitz
Just returning -errno in some cases prevents
trace_qcow2_l2_allocate_done from being executed (and, in one case, also
the unused allocated L2 table from being freed). Always going down the
error path fixes this.
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2-cluster.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 1c3d3fc..c442f6c 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -200,7 +200,8 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
if (l2_offset < 0) {
- return l2_offset;
+ ret = l2_offset;
+ goto fail;
}
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
@@ -213,7 +214,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
trace_qcow2_l2_allocate_get_empty(bs, l1_index);
ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
if (ret < 0) {
- return ret;
+ goto fail;
}
l2_table = *table;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache
2013-09-25 14:37 ` [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache Max Reitz
@ 2013-09-25 14:47 ` Benoît Canet
0 siblings, 0 replies; 11+ messages in thread
From: Benoît Canet @ 2013-09-25 14:47 UTC (permalink / raw)
To: Max Reitz; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
Le Wednesday 25 Sep 2013 à 16:37:18 (+0200), Max Reitz a écrit :
> In l2_allocate, the fail path is executed if qcow2_cache_flush fails.
> However, the L2 table has not yet been fetched from the L2 table cache.
> The qcow2_cache_put in the fail path therefore basically gives an
> undefined argument as the L2 table address (in this case).
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block/qcow2-cluster.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index 738ff73..f6d47c9 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c
> @@ -188,7 +188,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
> {
> BDRVQcowState *s = bs->opaque;
> uint64_t old_l2_offset;
> - uint64_t *l2_table;
> + uint64_t *l2_table = NULL;
> int64_t l2_offset;
> int ret;
>
> @@ -265,7 +265,9 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
>
> fail:
> trace_qcow2_l2_allocate_done(bs, l1_index, ret);
> - qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
> + if (l2_table != NULL) {
> + qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
> + }
> s->l1_table[l1_index] = old_l2_offset;
> return ret;
> }
> --
> 1.8.3.1
>
>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error
2013-09-25 14:37 ` [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error Max Reitz
@ 2013-09-25 14:50 ` Benoît Canet
2013-09-27 14:54 ` Kevin Wolf
1 sibling, 0 replies; 11+ messages in thread
From: Benoît Canet @ 2013-09-25 14:50 UTC (permalink / raw)
To: Max Reitz; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
Le Wednesday 25 Sep 2013 à 16:37:19 (+0200), Max Reitz a écrit :
> If an error occurs in l2_allocate, the allocated (but unused) L2 cluster
> should be freed.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block/qcow2-cluster.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index f6d47c9..1c3d3fc 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c
> @@ -269,6 +269,10 @@ fail:
> qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
> }
> s->l1_table[l1_index] = old_l2_offset;
> + if (l2_offset > 0) {
> + qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),
> + QCOW2_DISCARD_ALWAYS);
> + }
> return ret;
> }
>
> --
> 1.8.3.1
>
>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 3/3] qcow2: Always use error path in l2_allocate
2013-09-25 14:37 ` [Qemu-devel] [PATCH 3/3] qcow2: Always use error path in l2_allocate Max Reitz
@ 2013-09-25 14:56 ` Benoît Canet
0 siblings, 0 replies; 11+ messages in thread
From: Benoît Canet @ 2013-09-25 14:56 UTC (permalink / raw)
To: Max Reitz; +Cc: Kevin Wolf, qemu-devel, Stefan Hajnoczi
Le Wednesday 25 Sep 2013 à 16:37:20 (+0200), Max Reitz a écrit :
> Just returning -errno in some cases prevents
> trace_qcow2_l2_allocate_done from being executed (and, in one case, also
> the unused allocated L2 table from being freed). Always going down the
> error path fixes this.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block/qcow2-cluster.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index 1c3d3fc..c442f6c 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c
> @@ -200,7 +200,8 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
>
> l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
> if (l2_offset < 0) {
> - return l2_offset;
> + ret = l2_offset;
> + goto fail;
> }
>
> ret = qcow2_cache_flush(bs, s->refcount_block_cache);
> @@ -213,7 +214,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
> trace_qcow2_l2_allocate_get_empty(bs, l1_index);
> ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
> if (ret < 0) {
> - return ret;
> + goto fail;
> }
>
> l2_table = *table;
> --
> 1.8.3.1
>
>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate
2013-09-25 14:37 [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Max Reitz
` (2 preceding siblings ...)
2013-09-25 14:37 ` [Qemu-devel] [PATCH 3/3] qcow2: Always use error path in l2_allocate Max Reitz
@ 2013-09-27 9:38 ` Kevin Wolf
3 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2013-09-27 9:38 UTC (permalink / raw)
To: Max Reitz; +Cc: qemu-devel, Stefan Hajnoczi
Am 25.09.2013 um 16:37 hat Max Reitz geschrieben:
> Errors in l2_allocate should always go down the error path. If this path
> is taken, the newly allocated L2 cluster is abandoned and should thus be
> freed. The L2 table on the other hand should only be put back into the
> cache if it was taken from it before.
>
> Max Reitz (3):
> qcow2: Don't put invalid L2 table into cache
> qcow2: Free allocated L2 cluster on error
> qcow2: Always use error path in l2_allocate
>
> block/qcow2-cluster.c | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)
Thanks, applied all to the block branch.
Kevin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error
2013-09-25 14:37 ` [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error Max Reitz
2013-09-25 14:50 ` Benoît Canet
@ 2013-09-27 14:54 ` Kevin Wolf
2013-09-30 9:48 ` Max Reitz
1 sibling, 1 reply; 11+ messages in thread
From: Kevin Wolf @ 2013-09-27 14:54 UTC (permalink / raw)
To: Max Reitz; +Cc: qemu-devel, Stefan Hajnoczi
Am 25.09.2013 um 16:37 hat Max Reitz geschrieben:
> If an error occurs in l2_allocate, the allocated (but unused) L2 cluster
> should be freed.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
> block/qcow2-cluster.c | 4 ++++
> 1 file changed, 4 insertions(+)
This needs an update of the reference output for test case 026 (both for
-nocache and writethrough).
Most of the changes look expected and good, like cluster leaks
disappearing. With -nocache, however, there are a few cases that failed
previously and result in successful writes now. It would be interesting
to see the explanation for these before we merge the patch.
Kevin
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error
2013-09-27 14:54 ` Kevin Wolf
@ 2013-09-30 9:48 ` Max Reitz
2013-09-30 11:24 ` Kevin Wolf
0 siblings, 1 reply; 11+ messages in thread
From: Max Reitz @ 2013-09-30 9:48 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel, Stefan Hajnoczi
On 2013-09-27 16:54, Kevin Wolf wrote:
> Am 25.09.2013 um 16:37 hat Max Reitz geschrieben:
>> If an error occurs in l2_allocate, the allocated (but unused) L2 cluster
>> should be freed.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>> block/qcow2-cluster.c | 4 ++++
>> 1 file changed, 4 insertions(+)
> This needs an update of the reference output for test case 026 (both for
> -nocache and writethrough).
Yes, right.
> Most of the changes look expected and good, like cluster leaks
> disappearing. With -nocache, however, there are a few cases that failed
> previously and result in successful writes now. It would be interesting
> to see the explanation for these before we merge the patch.
I personally don't see this cases. Could you give an example?
Max
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error
2013-09-30 9:48 ` Max Reitz
@ 2013-09-30 11:24 ` Kevin Wolf
0 siblings, 0 replies; 11+ messages in thread
From: Kevin Wolf @ 2013-09-30 11:24 UTC (permalink / raw)
To: Max Reitz; +Cc: qemu-devel, Stefan Hajnoczi
Am 30.09.2013 um 11:48 hat Max Reitz geschrieben:
> On 2013-09-27 16:54, Kevin Wolf wrote:
> >Am 25.09.2013 um 16:37 hat Max Reitz geschrieben:
> >>If an error occurs in l2_allocate, the allocated (but unused) L2 cluster
> >>should be freed.
> >>
> >>Signed-off-by: Max Reitz <mreitz@redhat.com>
> >>---
> >> block/qcow2-cluster.c | 4 ++++
> >> 1 file changed, 4 insertions(+)
> >This needs an update of the reference output for test case 026 (both for
> >-nocache and writethrough).
> Yes, right.
>
> >Most of the changes look expected and good, like cluster leaks
> >disappearing. With -nocache, however, there are a few cases that failed
> >previously and result in successful writes now. It would be interesting
> >to see the explanation for these before we merge the patch.
> I personally don't see this cases. Could you give an example?
Weird, I can't reproduce it any more. I guess it was a problem on my side
then.
Kevin
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2013-09-30 11:24 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-25 14:37 [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Max Reitz
2013-09-25 14:37 ` [Qemu-devel] [PATCH 1/3] qcow2: Don't put invalid L2 table into cache Max Reitz
2013-09-25 14:47 ` Benoît Canet
2013-09-25 14:37 ` [Qemu-devel] [PATCH 2/3] qcow2: Free allocated L2 cluster on error Max Reitz
2013-09-25 14:50 ` Benoît Canet
2013-09-27 14:54 ` Kevin Wolf
2013-09-30 9:48 ` Max Reitz
2013-09-30 11:24 ` Kevin Wolf
2013-09-25 14:37 ` [Qemu-devel] [PATCH 3/3] qcow2: Always use error path in l2_allocate Max Reitz
2013-09-25 14:56 ` Benoît Canet
2013-09-27 9:38 ` [Qemu-devel] [PATCH 0/3] qcow2: Small error path fixes for l2_allocate Kevin Wolf
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).