]> git.proxmox.com Git - ceph.git/blame - ceph/src/librbd/io/AioCompletion.cc
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / librbd / io / AioCompletion.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "librbd/io/AioCompletion.h"
5#include <errno.h>
6
7#include "common/ceph_context.h"
8#include "common/dout.h"
9#include "common/errno.h"
10#include "common/perf_counters.h"
11#include "common/WorkQueue.h"
12
13#include "librbd/ImageCtx.h"
14#include "librbd/internal.h"
7c673cae 15#include "librbd/Journal.h"
b32b8144 16#include "librbd/Types.h"
7c673cae
FG
17
18#ifdef WITH_LTTNG
19#include "tracing/librbd.h"
20#else
21#define tracepoint(...)
22#endif
23
24#define dout_subsys ceph_subsys_rbd
25#undef dout_prefix
26#define dout_prefix *_dout << "librbd::io::AioCompletion: " << this \
27 << " " << __func__ << ": "
28
29namespace librbd {
30namespace io {
31
32int AioCompletion::wait_for_complete() {
33 tracepoint(librbd, aio_wait_for_complete_enter, this);
34 lock.Lock();
35 while (state != AIO_STATE_COMPLETE)
36 cond.Wait(lock);
37 lock.Unlock();
38 tracepoint(librbd, aio_wait_for_complete_exit, 0);
39 return 0;
40}
41
42void AioCompletion::finalize(ssize_t rval)
43{
11fdf7f2
TL
44 ceph_assert(lock.is_locked());
45 ceph_assert(ictx != nullptr);
7c673cae
FG
46 CephContext *cct = ictx->cct;
47
48 ldout(cct, 20) << "r=" << rval << dendl;
49 if (rval >= 0 && aio_type == AIO_TYPE_READ) {
50 read_result.assemble_result(cct);
51 }
52}
53
54void AioCompletion::complete() {
11fdf7f2
TL
55 ceph_assert(lock.is_locked());
56 ceph_assert(ictx != nullptr);
7c673cae
FG
57 CephContext *cct = ictx->cct;
58
59 tracepoint(librbd, aio_complete_enter, this, rval);
11fdf7f2
TL
60 if (ictx->perfcounter != nullptr) {
61 ceph::timespan elapsed = coarse_mono_clock::now() - start_time;
62 switch (aio_type) {
63 case AIO_TYPE_GENERIC:
64 case AIO_TYPE_OPEN:
65 case AIO_TYPE_CLOSE:
66 break;
67 case AIO_TYPE_READ:
68 ictx->perfcounter->tinc(l_librbd_rd_latency, elapsed); break;
69 case AIO_TYPE_WRITE:
70 ictx->perfcounter->tinc(l_librbd_wr_latency, elapsed); break;
71 case AIO_TYPE_DISCARD:
72 ictx->perfcounter->tinc(l_librbd_discard_latency, elapsed); break;
73 case AIO_TYPE_FLUSH:
74 ictx->perfcounter->tinc(l_librbd_flush_latency, elapsed); break;
75 case AIO_TYPE_WRITESAME:
76 ictx->perfcounter->tinc(l_librbd_ws_latency, elapsed); break;
77 case AIO_TYPE_COMPARE_AND_WRITE:
78 ictx->perfcounter->tinc(l_librbd_cmp_latency, elapsed); break;
79 default:
80 lderr(cct) << "completed invalid aio_type: " << aio_type << dendl;
81 break;
82 }
7c673cae
FG
83 }
84
81eedcae
TL
85 if ((aio_type == AIO_TYPE_CLOSE) ||
86 (aio_type == AIO_TYPE_OPEN && rval < 0)) {
87 // must destroy ImageCtx prior to invoking callback
88 delete ictx;
89 ictx = nullptr;
90 }
91
7c673cae
FG
92 state = AIO_STATE_CALLBACK;
93 if (complete_cb) {
94 lock.Unlock();
95 complete_cb(rbd_comp, complete_arg);
96 lock.Lock();
97 }
98
81eedcae 99 if (ictx != nullptr && event_notify && ictx->event_socket.is_valid()) {
7c673cae
FG
100 ictx->completed_reqs_lock.Lock();
101 ictx->completed_reqs.push_back(&m_xlist_item);
102 ictx->completed_reqs_lock.Unlock();
103 ictx->event_socket.notify();
104 }
105
106 state = AIO_STATE_COMPLETE;
107 cond.Signal();
108
109 // note: possible for image to be closed after op marked finished
110 if (async_op.started()) {
111 async_op.finish_op();
112 }
113 tracepoint(librbd, aio_complete_exit);
114}
115
116void AioCompletion::init_time(ImageCtx *i, aio_type_t t) {
117 Mutex::Locker locker(lock);
118 if (ictx == nullptr) {
119 ictx = i;
120 aio_type = t;
11fdf7f2 121 start_time = coarse_mono_clock::now();
7c673cae
FG
122 }
123}
124
494da23a 125void AioCompletion::start_op() {
7c673cae 126 Mutex::Locker locker(lock);
11fdf7f2 127 ceph_assert(ictx != nullptr);
81eedcae
TL
128
129 if (aio_type == AIO_TYPE_OPEN || aio_type == AIO_TYPE_CLOSE) {
130 // no need to track async open/close operations
131 return;
132 }
133
494da23a
TL
134 ceph_assert(!async_op.started());
135 async_op.start_op(*ictx);
7c673cae
FG
136}
137
138void AioCompletion::fail(int r)
139{
140 lock.Lock();
11fdf7f2 141 ceph_assert(ictx != nullptr);
7c673cae
FG
142 CephContext *cct = ictx->cct;
143
144 lderr(cct) << cpp_strerror(r) << dendl;
11fdf7f2 145 ceph_assert(pending_count == 0);
7c673cae
FG
146 rval = r;
147 complete();
148 put_unlock();
149}
150
151void AioCompletion::set_request_count(uint32_t count) {
152 lock.Lock();
11fdf7f2 153 ceph_assert(ictx != nullptr);
7c673cae
FG
154 CephContext *cct = ictx->cct;
155
156 ldout(cct, 20) << "pending=" << count << dendl;
11fdf7f2 157 ceph_assert(pending_count == 0);
7c673cae 158
81eedcae
TL
159 if (count > 0) {
160 pending_count = count;
161 lock.Unlock();
162 } else {
163 pending_count = 1;
164 lock.Unlock();
165
166 // ensure completion fires in clean lock context
167 ictx->op_work_queue->queue(new C_AioRequest(this), 0);
168 }
7c673cae
FG
169}
170
171void AioCompletion::complete_request(ssize_t r)
172{
173 lock.Lock();
11fdf7f2 174 ceph_assert(ictx != nullptr);
7c673cae
FG
175 CephContext *cct = ictx->cct;
176
177 if (rval >= 0) {
178 if (r < 0 && r != -EEXIST)
179 rval = r;
180 else if (r > 0)
181 rval += r;
182 }
11fdf7f2 183 ceph_assert(pending_count);
7c673cae
FG
184 int count = --pending_count;
185
186 ldout(cct, 20) << "cb=" << complete_cb << ", "
187 << "pending=" << pending_count << dendl;
81eedcae 188 if (!count) {
7c673cae
FG
189 finalize(rval);
190 complete();
191 }
192 put_unlock();
193}
194
7c673cae
FG
195bool AioCompletion::is_complete() {
196 tracepoint(librbd, aio_is_complete_enter, this);
197 bool done;
198 {
199 Mutex::Locker l(lock);
200 done = this->state == AIO_STATE_COMPLETE;
201 }
202 tracepoint(librbd, aio_is_complete_exit, done);
203 return done;
204}
205
206ssize_t AioCompletion::get_return_value() {
207 tracepoint(librbd, aio_get_return_value_enter, this);
208 lock.Lock();
209 ssize_t r = rval;
210 lock.Unlock();
211 tracepoint(librbd, aio_get_return_value_exit, r);
212 return r;
213}
214
215} // namespace io
216} // namespace librbd