]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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/UpdateRequest.h" | |
5 | #include "include/rbd/object_map_types.h" | |
6 | #include "include/stringify.h" | |
7 | #include "common/dout.h" | |
8 | #include "librbd/ImageCtx.h" | |
9 | #include "librbd/ObjectMap.h" | |
10 | #include "cls/lock/cls_lock_client.h" | |
11 | #include <string> | |
12 | ||
13 | #define dout_subsys ceph_subsys_rbd | |
14 | #undef dout_prefix | |
15 | #define dout_prefix *_dout << "librbd::object_map::UpdateRequest: " | |
16 | ||
17 | namespace librbd { | |
18 | namespace object_map { | |
19 | ||
20 | template <typename I> | |
21 | void UpdateRequest<I>::send() { | |
22 | assert(m_image_ctx.snap_lock.is_locked()); | |
23 | assert(m_image_ctx.object_map_lock.is_locked()); | |
24 | CephContext *cct = m_image_ctx.cct; | |
25 | ||
26 | // safe to update in-memory state first without handling rollback since any | |
27 | // failures will invalidate the object map | |
28 | std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id, m_snap_id)); | |
29 | ldout(cct, 20) << this << " updating object map" | |
30 | << ": ictx=" << &m_image_ctx << ", oid=" << oid << ", [" | |
31 | << m_start_object_no << "," << m_end_object_no << ") = " | |
32 | << (m_current_state ? | |
33 | stringify(static_cast<uint32_t>(*m_current_state)) : "") | |
34 | << "->" << static_cast<uint32_t>(m_new_state) | |
35 | << dendl; | |
36 | ||
37 | librados::ObjectWriteOperation op; | |
38 | if (m_snap_id == CEPH_NOSNAP) { | |
39 | rados::cls::lock::assert_locked(&op, RBD_LOCK_NAME, LOCK_EXCLUSIVE, "", ""); | |
40 | } | |
41 | cls_client::object_map_update(&op, m_start_object_no, m_end_object_no, | |
42 | m_new_state, m_current_state); | |
43 | ||
44 | librados::AioCompletion *rados_completion = create_callback_completion(); | |
31f18b77 FG |
45 | std::vector<librados::snap_t> snaps; |
46 | int r = m_image_ctx.md_ctx.aio_operate( | |
47 | oid, rados_completion, &op, 0, snaps, | |
48 | (m_trace.valid() ? m_trace.get_info() : nullptr)); | |
7c673cae FG |
49 | assert(r == 0); |
50 | rados_completion->release(); | |
51 | } | |
52 | ||
53 | template <typename I> | |
54 | void UpdateRequest<I>::finish_request() { | |
55 | RWLock::RLocker snap_locker(m_image_ctx.snap_lock); | |
56 | RWLock::WLocker object_map_locker(m_image_ctx.object_map_lock); | |
57 | ldout(m_image_ctx.cct, 20) << this << " on-disk object map updated" | |
58 | << dendl; | |
59 | ||
60 | // rebuilding the object map might update on-disk only | |
61 | if (m_snap_id == m_image_ctx.snap_id) { | |
62 | for (uint64_t object_no = m_start_object_no; | |
63 | object_no < MIN(m_end_object_no, m_object_map.size()); | |
64 | ++object_no) { | |
65 | uint8_t state = m_object_map[object_no]; | |
66 | if (!m_current_state || state == *m_current_state || | |
67 | (*m_current_state == OBJECT_EXISTS && state == OBJECT_EXISTS_CLEAN)) { | |
68 | m_object_map[object_no] = m_new_state; | |
69 | } | |
70 | } | |
71 | } | |
72 | } | |
73 | ||
74 | } // namespace object_map | |
75 | } // namespace librbd | |
76 | ||
77 | template class librbd::object_map::UpdateRequest<librbd::ImageCtx>; |