]>
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 "include/ceph_assert.h"
6 #include "common/dout.h"
7 #include "librbd/AsioEngine.h"
8 #include "librbd/ImageCtx.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
,
24 std::list
<Context
*> &&flush_contexts
)
25 : image_ctx(image_ctx
), flush_contexts(std::move(flush_contexts
)) {
27 void finish(int r
) override
{
28 std::shared_lock owner_locker
{image_ctx
->owner_lock
};
29 while (!flush_contexts
.empty()) {
30 Context
*flush_ctx
= flush_contexts
.front();
31 flush_contexts
.pop_front();
33 ldout(image_ctx
->cct
, 20) << "completed flush: " << flush_ctx
<< dendl
;
34 flush_ctx
->complete(0);
39 } // anonymous namespace
41 void AsyncOperation::start_op(ImageCtx
&image_ctx
) {
42 ceph_assert(m_image_ctx
== NULL
);
43 m_image_ctx
= &image_ctx
;
45 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< dendl
;
46 std::lock_guard l
{m_image_ctx
->async_ops_lock
};
47 m_image_ctx
->async_ops
.push_front(&m_xlist_item
);
50 void AsyncOperation::finish_op() {
51 ldout(m_image_ctx
->cct
, 20) << this << " " << __func__
<< dendl
;
54 std::lock_guard l
{m_image_ctx
->async_ops_lock
};
55 xlist
<AsyncOperation
*>::iterator
iter(&m_xlist_item
);
57 ceph_assert(m_xlist_item
.remove_myself());
59 // linked list stored newest -> oldest ops
60 if (!iter
.end() && !m_flush_contexts
.empty()) {
61 ldout(m_image_ctx
->cct
, 20) << "moving flush contexts to previous op: "
63 (*iter
)->m_flush_contexts
.insert((*iter
)->m_flush_contexts
.end(),
64 m_flush_contexts
.begin(),
65 m_flush_contexts
.end());
70 if (!m_flush_contexts
.empty()) {
71 C_CompleteFlushes
*ctx
= new C_CompleteFlushes(m_image_ctx
,
72 std::move(m_flush_contexts
));
73 m_image_ctx
->asio_engine
->post(ctx
, 0);
77 void AsyncOperation::flush(Context
* on_finish
) {
79 std::lock_guard locker
{m_image_ctx
->async_ops_lock
};
80 xlist
<AsyncOperation
*>::iterator
iter(&m_xlist_item
);
83 // linked list stored newest -> oldest ops
85 (*iter
)->m_flush_contexts
.push_back(on_finish
);
90 m_image_ctx
->asio_engine
->post(on_finish
, 0);