]>
git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/AsyncOperation.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "librbd/AsyncOperation.h"
4 #include "librbd/ImageCtx.h"
5 #include "common/dout.h"
6 #include "common/WorkQueue.h"
7 #include "include/assert.h"
9 #define dout_subsys ceph_subsys_rbd
11 #define dout_prefix *_dout << "librbd::AsyncOperation: "
17 struct C_CompleteFlushes
: public Context
{
19 std::list
<Context
*> flush_contexts
;
21 explicit C_CompleteFlushes(ImageCtx
*image_ctx
, std::list
<Context
*> &&flush_contexts
)
22 : image_ctx(image_ctx
), flush_contexts(std::move(flush_contexts
)) {
24 void finish(int r
) override
{
25 RWLock::RLocker
owner_locker(image_ctx
->owner_lock
);
26 while (!flush_contexts
.empty()) {
27 Context
*flush_ctx
= flush_contexts
.front();
28 flush_contexts
.pop_front();
30 ldout(image_ctx
->cct
, 20) << "completed flush: " << flush_ctx
<< dendl
;
31 flush_ctx
->complete(0);
36 } // anonymous namespace
38 void AsyncOperation::start_op(ImageCtx
&image_ctx
) {
39 assert(m_image_ctx
== NULL
);
40 m_image_ctx
= &image_ctx
;
42 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< dendl
;
43 Mutex::Locker
l(m_image_ctx
->async_ops_lock
);
44 m_image_ctx
->async_ops
.push_front(&m_xlist_item
);
47 void AsyncOperation::finish_op() {
48 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< dendl
;
51 Mutex::Locker
l(m_image_ctx
->async_ops_lock
);
52 xlist
<AsyncOperation
*>::iterator
iter(&m_xlist_item
);
54 assert(m_xlist_item
.remove_myself());
56 // linked list stored newest -> oldest ops
57 if (!iter
.end() && !m_flush_contexts
.empty()) {
58 ldout(m_image_ctx
->cct
, 20) << "moving flush contexts to previous op: "
60 (*iter
)->m_flush_contexts
.insert((*iter
)->m_flush_contexts
.end(),
61 m_flush_contexts
.begin(),
62 m_flush_contexts
.end());
67 if (!m_flush_contexts
.empty()) {
68 C_CompleteFlushes
*ctx
= new C_CompleteFlushes(m_image_ctx
,
69 std::move(m_flush_contexts
));
70 m_image_ctx
->op_work_queue
->queue(ctx
);
74 void AsyncOperation::add_flush_context(Context
*on_finish
) {
75 assert(m_image_ctx
->async_ops_lock
.is_locked());
76 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< ": "
77 << "flush=" << on_finish
<< dendl
;
78 m_flush_contexts
.push_back(on_finish
);