]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/object_map/SnapshotRollbackRequest.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / librbd / object_map / SnapshotRollbackRequest.cc
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/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"
10 #include <iostream>
11
12 #define dout_subsys ceph_subsys_rbd
13 #undef dout_prefix
14 #define dout_prefix *_dout << "librbd::object_map::SnapshotRollbackRequest: "
15
16 namespace librbd {
17 namespace object_map {
18
19 namespace {
20
21 std::ostream& operator<<(std::ostream& os,
22 const SnapshotRollbackRequest::State& state) {
23 switch(state) {
24 case SnapshotRollbackRequest::STATE_READ_MAP:
25 os << "READ_MAP";
26 break;
27 case SnapshotRollbackRequest::STATE_INVALIDATE_MAP:
28 os << "INVALIDATE_MAP";
29 break;
30 case SnapshotRollbackRequest::STATE_WRITE_MAP:
31 os << "WRITE_MAP";
32 break;
33 default:
34 os << "UNKNOWN (" << static_cast<uint32_t>(state) << ")";
35 break;
36 }
37 return os;
38 }
39
40 } // anonymous namespace
41
42 void SnapshotRollbackRequest::send() {
43 send_read_map();
44 }
45
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) {
51 m_ret_val = r;
52 }
53
54 bool finished = false;
55 switch (m_state) {
56 case STATE_READ_MAP:
57 if (r < 0) {
58 // invalidate the snapshot object map
59 send_invalidate_map();
60 } else {
61 send_write_map();
62 }
63 break;
64 case STATE_INVALIDATE_MAP:
65 // invalidate the HEAD object map as well
66 finished = Request::should_complete(m_ret_val);
67 break;
68 case STATE_WRITE_MAP:
69 finished = Request::should_complete(r);
70 break;
71 default:
72 assert(false);
73 break;
74 }
75 return finished;
76 }
77
78 void SnapshotRollbackRequest::send_read_map() {
79 std::string snap_oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id));
80
81 CephContext *cct = m_image_ctx.cct;
82 ldout(cct, 5) << this << " " << __func__ << ": snap_oid=" << snap_oid
83 << dendl;
84 m_state = STATE_READ_MAP;
85
86 librados::ObjectReadOperation op;
87 op.read(0, 0, NULL, NULL);
88
89 librados::AioCompletion *rados_completion = create_callback_completion();
90 int r = m_image_ctx.md_ctx.aio_operate(snap_oid, rados_completion, &op,
91 &m_read_bl);
92 assert(r == 0);
93 rados_completion->release();
94 }
95
96 void SnapshotRollbackRequest::send_write_map() {
97 RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
98
99 CephContext *cct = m_image_ctx.cct;
100 std::string snap_oid(ObjectMap<>::object_map_name(m_image_ctx.id,
101 CEPH_NOSNAP));
102 ldout(cct, 5) << this << " " << __func__ << ": snap_oid=" << snap_oid
103 << dendl;
104 m_state = STATE_WRITE_MAP;
105
106 librados::ObjectWriteOperation op;
107 rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", "");
108 op.write_full(m_read_bl);
109
110 librados::AioCompletion *rados_completion = create_callback_completion();
111 int r = m_image_ctx.md_ctx.aio_operate(snap_oid, rados_completion, &op);
112 assert(r == 0);
113 rados_completion->release();
114 }
115
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);
119
120 CephContext *cct = m_image_ctx.cct;
121 ldout(cct, 5) << this << " " << __func__ << dendl;
122 m_state = STATE_INVALIDATE_MAP;
123
124 InvalidateRequest<> *req = new InvalidateRequest<>(m_image_ctx, m_snap_id,
125 false,
126 create_callback_context());
127 req->send();
128 }
129
130 } // namespace object_map
131 } // namespace librbd