]>
Commit | Line | Data |
---|---|---|
90a6d957 WB |
1 | From 40bb673c38565bb8660f15f088a85bb0fd12ab82 Mon Sep 17 00:00:00 2001 |
2 | From: Anton Nefedov <anton.nefedov@virtuozzo.com> | |
3 | Date: Wed, 26 Apr 2017 11:33:15 +0300 | |
4 | Subject: [PATCH 02/15] qemu-img: wait for convert coroutines to complete | |
5 | ||
6 | On error path (like i/o error in one of the coroutines), it's required to | |
7 | - wait for coroutines completion before cleaning the common structures | |
8 | - reenter dependent coroutines so they ever finish | |
9 | ||
10 | Introduced in 2d9187bc65. | |
11 | ||
12 | Cc: qemu-stable@nongnu.org | |
13 | Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com> | |
14 | Reviewed-by: Peter Lieven <pl@kamp.de> | |
15 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> | |
16 | --- | |
17 | qemu-img.c | 26 +++++++++++--------------- | |
18 | 1 file changed, 11 insertions(+), 15 deletions(-) | |
19 | ||
20 | diff --git a/qemu-img.c b/qemu-img.c | |
21 | index 4f7f458dd2..cf9885b75b 100644 | |
22 | --- a/qemu-img.c | |
23 | +++ b/qemu-img.c | |
24 | @@ -1761,13 +1761,13 @@ static void coroutine_fn convert_co_do_copy(void *opaque) | |
25 | qemu_co_mutex_lock(&s->lock); | |
26 | if (s->ret != -EINPROGRESS || s->sector_num >= s->total_sectors) { | |
27 | qemu_co_mutex_unlock(&s->lock); | |
28 | - goto out; | |
29 | + break; | |
30 | } | |
31 | n = convert_iteration_sectors(s, s->sector_num); | |
32 | if (n < 0) { | |
33 | qemu_co_mutex_unlock(&s->lock); | |
34 | s->ret = n; | |
35 | - goto out; | |
36 | + break; | |
37 | } | |
38 | /* save current sector and allocation status to local variables */ | |
39 | sector_num = s->sector_num; | |
40 | @@ -1792,7 +1792,6 @@ static void coroutine_fn convert_co_do_copy(void *opaque) | |
41 | error_report("error while reading sector %" PRId64 | |
42 | ": %s", sector_num, strerror(-ret)); | |
43 | s->ret = ret; | |
44 | - goto out; | |
45 | } | |
46 | } else if (!s->min_sparse && status == BLK_ZERO) { | |
47 | status = BLK_DATA; | |
48 | @@ -1801,22 +1800,20 @@ static void coroutine_fn convert_co_do_copy(void *opaque) | |
49 | ||
50 | if (s->wr_in_order) { | |
51 | /* keep writes in order */ | |
52 | - while (s->wr_offs != sector_num) { | |
53 | - if (s->ret != -EINPROGRESS) { | |
54 | - goto out; | |
55 | - } | |
56 | + while (s->wr_offs != sector_num && s->ret == -EINPROGRESS) { | |
57 | s->wait_sector_num[index] = sector_num; | |
58 | qemu_coroutine_yield(); | |
59 | } | |
60 | s->wait_sector_num[index] = -1; | |
61 | } | |
62 | ||
63 | - ret = convert_co_write(s, sector_num, n, buf, status); | |
64 | - if (ret < 0) { | |
65 | - error_report("error while writing sector %" PRId64 | |
66 | - ": %s", sector_num, strerror(-ret)); | |
67 | - s->ret = ret; | |
68 | - goto out; | |
69 | + if (s->ret == -EINPROGRESS) { | |
70 | + ret = convert_co_write(s, sector_num, n, buf, status); | |
71 | + if (ret < 0) { | |
72 | + error_report("error while writing sector %" PRId64 | |
73 | + ": %s", sector_num, strerror(-ret)); | |
74 | + s->ret = ret; | |
75 | + } | |
76 | } | |
77 | ||
78 | if (s->wr_in_order) { | |
79 | @@ -1837,7 +1834,6 @@ static void coroutine_fn convert_co_do_copy(void *opaque) | |
80 | } | |
81 | } | |
82 | ||
83 | -out: | |
84 | qemu_vfree(buf); | |
85 | s->co[index] = NULL; | |
86 | s->running_coroutines--; | |
87 | @@ -1899,7 +1895,7 @@ static int convert_do_copy(ImgConvertState *s) | |
88 | qemu_coroutine_enter(s->co[i]); | |
89 | } | |
90 | ||
91 | - while (s->ret == -EINPROGRESS) { | |
92 | + while (s->running_coroutines) { | |
93 | main_loop_wait(false); | |
94 | } | |
95 | ||
96 | -- | |
97 | 2.11.0 | |
98 |