Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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