]>
Commit | Line | Data |
---|---|---|
54619c4a DM |
1 | From dc7588c1eb3008bda53dde1d6b890cd299758155 Mon Sep 17 00:00:00 2001 |
2 | From: Josh Durgin <josh.durgin@inktank.com> | |
3 | Date: Fri, 29 Mar 2013 13:03:23 -0700 | |
4 | Subject: [PATCH] rbd: add an asynchronous flush | |
5 | ||
6 | The existing bdrv_co_flush_to_disk implementation uses rbd_flush(), | |
7 | which is sychronous and causes the main qemu thread to block until it | |
8 | is complete. This results in unresponsiveness and extra latency for | |
9 | the guest. | |
10 | ||
11 | Fix this by using an asynchronous version of flush. This was added to | |
12 | librbd with a special #define to indicate its presence, since it will | |
13 | be backported to stable versions. Thus, there is no need to check the | |
14 | version of librbd. | |
15 | ||
16 | Implement this as bdrv_aio_flush, since it matches other aio functions | |
17 | in the rbd block driver, and leave out bdrv_co_flush_to_disk when the | |
18 | asynchronous version is available. | |
19 | ||
20 | Reported-by: Oliver Francke <oliver@filoo.de> | |
21 | Signed-off-by: Josh Durgin <josh.durgin@inktank.com> | |
22 | Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> | |
23 | --- | |
24 | block/rbd.c | 37 +++++++++++++++++++++++++++++++++---- | |
25 | 1 files changed, 33 insertions(+), 4 deletions(-) | |
26 | ||
27 | diff --git a/block/rbd.c b/block/rbd.c | |
28 | index 1a8ea6d..141b488 100644 | |
29 | --- a/block/rbd.c | |
30 | +++ b/block/rbd.c | |
31 | @@ -63,7 +63,8 @@ | |
32 | typedef enum { | |
33 | RBD_AIO_READ, | |
34 | RBD_AIO_WRITE, | |
35 | - RBD_AIO_DISCARD | |
36 | + RBD_AIO_DISCARD, | |
37 | + RBD_AIO_FLUSH | |
38 | } RBDAIOCmd; | |
39 | ||
40 | typedef struct RBDAIOCB { | |
41 | @@ -379,8 +380,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb) | |
42 | ||
43 | r = rcb->ret; | |
44 | ||
45 | - if (acb->cmd == RBD_AIO_WRITE || | |
46 | - acb->cmd == RBD_AIO_DISCARD) { | |
47 | + if (acb->cmd != RBD_AIO_READ) { | |
48 | if (r < 0) { | |
49 | acb->ret = r; | |
50 | acb->error = 1; | |
51 | @@ -659,6 +659,16 @@ static int rbd_aio_discard_wrapper(rbd_image_t image, | |
52 | #endif | |
53 | } | |
54 | ||
55 | +static int rbd_aio_flush_wrapper(rbd_image_t image, | |
56 | + rbd_completion_t comp) | |
57 | +{ | |
58 | +#ifdef LIBRBD_SUPPORTS_AIO_FLUSH | |
59 | + return rbd_aio_flush(image, comp); | |
60 | +#else | |
61 | + return -ENOTSUP; | |
62 | +#endif | |
63 | +} | |
64 | + | |
65 | static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs, | |
66 | int64_t sector_num, | |
67 | QEMUIOVector *qiov, | |
68 | @@ -679,7 +689,7 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs, | |
69 | acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque); | |
70 | acb->cmd = cmd; | |
71 | acb->qiov = qiov; | |
72 | - if (cmd == RBD_AIO_DISCARD) { | |
73 | + if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) { | |
74 | acb->bounce = NULL; | |
75 | } else { | |
76 | acb->bounce = qemu_blockalign(bs, qiov->size); | |
77 | @@ -723,6 +733,9 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs, | |
78 | case RBD_AIO_DISCARD: | |
79 | r = rbd_aio_discard_wrapper(s->image, off, size, c); | |
80 | break; | |
81 | + case RBD_AIO_FLUSH: | |
82 | + r = rbd_aio_flush_wrapper(s->image, c); | |
83 | + break; | |
84 | default: | |
85 | r = -EINVAL; | |
86 | } | |
87 | @@ -762,6 +775,16 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs, | |
88 | RBD_AIO_WRITE); | |
89 | } | |
90 | ||
91 | +#ifdef LIBRBD_SUPPORTS_AIO_FLUSH | |
92 | +static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs, | |
93 | + BlockDriverCompletionFunc *cb, | |
94 | + void *opaque) | |
95 | +{ | |
96 | + return rbd_start_aio(bs, 0, NULL, 0, cb, opaque, RBD_AIO_FLUSH); | |
97 | +} | |
98 | + | |
99 | +#else | |
100 | + | |
101 | static int qemu_rbd_co_flush(BlockDriverState *bs) | |
102 | { | |
103 | #if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1) | |
104 | @@ -772,6 +795,7 @@ static int qemu_rbd_co_flush(BlockDriverState *bs) | |
105 | return 0; | |
106 | #endif | |
107 | } | |
108 | +#endif | |
109 | ||
110 | static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi) | |
111 | { | |
112 | @@ -949,7 +973,12 @@ static BlockDriver bdrv_rbd = { | |
113 | ||
114 | .bdrv_aio_readv = qemu_rbd_aio_readv, | |
115 | .bdrv_aio_writev = qemu_rbd_aio_writev, | |
116 | + | |
117 | +#ifdef LIBRBD_SUPPORTS_AIO_FLUSH | |
118 | + .bdrv_aio_flush = qemu_rbd_aio_flush, | |
119 | +#else | |
120 | .bdrv_co_flush_to_disk = qemu_rbd_co_flush, | |
121 | +#endif | |
122 | ||
123 | #ifdef LIBRBD_SUPPORTS_DISCARD | |
124 | .bdrv_aio_discard = qemu_rbd_aio_discard, | |
125 | -- | |
126 | 1.7.0.4 | |
127 |