]>
git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/AsyncOperation.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/io/AsyncOperation.h"
5 #include "librbd/ImageCtx.h"
6 #include "common/dout.h"
7 #include "common/WorkQueue.h"
8 #include "include/assert.h"
10 #define dout_subsys ceph_subsys_rbd
12 #define dout_prefix *_dout << "librbd::io::AsyncOperation: "
19 struct C_CompleteFlushes
: public Context
{
21 std::list
<Context
*> flush_contexts
;
23 explicit C_CompleteFlushes(ImageCtx
*image_ctx
, std::list
<Context
*> &&flush_contexts
)
24 : image_ctx(image_ctx
), flush_contexts(std::move(flush_contexts
)) {
26 void finish(int r
) override
{
27 RWLock::RLocker
owner_locker(image_ctx
->owner_lock
);
28 while (!flush_contexts
.empty()) {
29 Context
*flush_ctx
= flush_contexts
.front();
30 flush_contexts
.pop_front();
32 ldout(image_ctx
->cct
, 20) << "completed flush: " << flush_ctx
<< dendl
;
33 flush_ctx
->complete(0);
38 } // anonymous namespace
40 void AsyncOperation::start_op(ImageCtx
&image_ctx
) {
41 assert(m_image_ctx
== NULL
);
42 m_image_ctx
= &image_ctx
;
44 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< dendl
;
45 Mutex::Locker
l(m_image_ctx
->async_ops_lock
);
46 m_image_ctx
->async_ops
.push_front(&m_xlist_item
);
49 void AsyncOperation::finish_op() {
50 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< dendl
;
53 Mutex::Locker
l(m_image_ctx
->async_ops_lock
);
54 xlist
<AsyncOperation
*>::iterator
iter(&m_xlist_item
);
56 assert(m_xlist_item
.remove_myself());
58 // linked list stored newest -> oldest ops
59 if (!iter
.end() && !m_flush_contexts
.empty()) {
60 ldout(m_image_ctx
->cct
, 20) << "moving flush contexts to previous op: "
62 (*iter
)->m_flush_contexts
.insert((*iter
)->m_flush_contexts
.end(),
63 m_flush_contexts
.begin(),
64 m_flush_contexts
.end());
69 if (!m_flush_contexts
.empty()) {
70 C_CompleteFlushes
*ctx
= new C_CompleteFlushes(m_image_ctx
,
71 std::move(m_flush_contexts
));
72 m_image_ctx
->op_work_queue
->queue(ctx
);
76 void AsyncOperation::add_flush_context(Context
*on_finish
) {
77 assert(m_image_ctx
->async_ops_lock
.is_locked());
78 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< ": "
79 << "flush=" << on_finish
<< dendl
;
80 m_flush_contexts
.push_back(on_finish
);