1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "librbd/object_map/SnapshotRollbackRequest.h"
5 #include "common/dout.h"
6 #include "librbd/ImageCtx.h"
7 #include "librbd/ObjectMap.h"
8 #include "librbd/object_map/InvalidateRequest.h"
9 #include "cls/lock/cls_lock_client.h"
12 #define dout_subsys ceph_subsys_rbd
14 #define dout_prefix *_dout << "librbd::object_map::SnapshotRollbackRequest: "
17 namespace object_map {
21 std::ostream& operator<<(std::ostream& os,
22 const SnapshotRollbackRequest::State& state) {
24 case SnapshotRollbackRequest::STATE_READ_MAP:
27 case SnapshotRollbackRequest::STATE_INVALIDATE_MAP:
28 os << "INVALIDATE_MAP";
30 case SnapshotRollbackRequest::STATE_WRITE_MAP:
34 os << "UNKNOWN (" << static_cast<uint32_t>(state) << ")";
40 } // anonymous namespace
42 void SnapshotRollbackRequest::send() {
46 bool SnapshotRollbackRequest::should_complete(int r) {
47 CephContext *cct = m_image_ctx.cct;
48 ldout(cct, 5) << this << " " << __func__ << ": state=" << m_state << ", "
49 << "r=" << r << dendl;
50 if (r < 0 && m_ret_val == 0) {
54 bool finished = false;
58 // invalidate the snapshot object map
59 send_invalidate_map();
64 case STATE_INVALIDATE_MAP:
65 // invalidate the HEAD object map as well
66 finished = Request::should_complete(m_ret_val);
69 finished = Request::should_complete(r);
78 void SnapshotRollbackRequest::send_read_map() {
79 std::string snap_oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id));
81 CephContext *cct = m_image_ctx.cct;
82 ldout(cct, 5) << this << " " << __func__ << ": snap_oid=" << snap_oid
84 m_state = STATE_READ_MAP;
86 librados::ObjectReadOperation op;
87 op.read(0, 0, NULL, NULL);
89 librados::AioCompletion *rados_completion = create_callback_completion();
90 int r = m_image_ctx.md_ctx.aio_operate(snap_oid, rados_completion, &op,
93 rados_completion->release();
96 void SnapshotRollbackRequest::send_write_map() {
97 RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
99 CephContext *cct = m_image_ctx.cct;
100 std::string snap_oid(ObjectMap<>::object_map_name(m_image_ctx.id,
102 ldout(cct, 5) << this << " " << __func__ << ": snap_oid=" << snap_oid
104 m_state = STATE_WRITE_MAP;
106 librados::ObjectWriteOperation op;
107 rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
108 op.write_full(m_read_bl);
110 librados::AioCompletion *rados_completion = create_callback_completion();
111 int r = m_image_ctx.md_ctx.aio_operate(snap_oid, rados_completion, &op);
113 rados_completion->release();
116 void SnapshotRollbackRequest::send_invalidate_map() {
117 RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
118 RWLock::WLocker snap_locker(m_image_ctx.snap_lock);
120 CephContext *cct = m_image_ctx.cct;
121 ldout(cct, 5) << this << " " << __func__ << dendl;
122 m_state = STATE_INVALIDATE_MAP;
124 InvalidateRequest<> *req = new InvalidateRequest<>(m_image_ctx, m_snap_id,
126 create_callback_context());
130 } // namespace object_map
131 } // namespace librbd