summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Dillaman <dillaman@redhat.com>2020-03-10 21:19:42 +0100
committerJason Dillaman <dillaman@redhat.com>2020-03-10 22:21:48 +0100
commit2b3a46801d3921220c82d9ded54ad76da6db0b91 (patch)
tree38ae9d49b54333bd68313008fa7c45a0ff64d099
parentlibrbd: helper state machine for computing diffs between object-maps (diff)
downloadceph-2b3a46801d3921220c82d9ded54ad76da6db0b91.tar.xz
ceph-2b3a46801d3921220c82d9ded54ad76da6db0b91.zip
librbd: switch diff-iterate API to use new object-map diff helper
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
-rw-r--r--src/librbd/api/DiffIterate.cc140
1 files changed, 14 insertions, 126 deletions
diff --git a/src/librbd/api/DiffIterate.cc b/src/librbd/api/DiffIterate.cc
index af61cd9e384..7e47c7ec3a8 100644
--- a/src/librbd/api/DiffIterate.cc
+++ b/src/librbd/api/DiffIterate.cc
@@ -10,6 +10,7 @@
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ImageDispatchSpec.h"
#include "librbd/io/ImageRequestWQ.h"
+#include "librbd/object_map/DiffRequest.h"
#include "include/rados/librados.hpp"
#include "include/interval_set.h"
#include "common/errno.h"
@@ -313,16 +314,19 @@ int DiffIterate<I>::execute() {
int r;
bool fast_diff_enabled = false;
BitVector<2> object_diff_state;
- {
- std::shared_lock image_locker{m_image_ctx.image_lock};
- if (m_whole_object && (m_image_ctx.features & RBD_FEATURE_FAST_DIFF) != 0) {
- r = diff_object_map(from_snap_id, end_snap_id, &object_diff_state);
- if (r < 0) {
- ldout(cct, 5) << "fast diff disabled" << dendl;
- } else {
- ldout(cct, 5) << "fast diff enabled" << dendl;
- fast_diff_enabled = true;
- }
+ if (m_whole_object) {
+ C_SaferCond ctx;
+ auto req = object_map::DiffRequest<I>::create(&m_image_ctx, from_snap_id,
+ end_snap_id,
+ &object_diff_state, &ctx);
+ req->send();
+
+ r = ctx.wait();
+ if (r < 0) {
+ ldout(cct, 5) << "fast diff disabled" << dendl;
+ } else {
+ ldout(cct, 5) << "fast diff enabled" << dendl;
+ fast_diff_enabled = true;
}
}
@@ -431,122 +435,6 @@ int DiffIterate<I>::execute() {
return 0;
}
-template <typename I>
-int DiffIterate<I>::diff_object_map(uint64_t from_snap_id, uint64_t to_snap_id,
- BitVector<2>* object_diff_state) {
- ceph_assert(ceph_mutex_is_locked(m_image_ctx.image_lock));
- CephContext* cct = m_image_ctx.cct;
-
- bool diff_from_start = (from_snap_id == 0);
- if (from_snap_id == 0) {
- if (!m_image_ctx.snaps.empty()) {
- from_snap_id = m_image_ctx.snaps.back();
- } else {
- from_snap_id = CEPH_NOSNAP;
- }
- }
-
- object_diff_state->clear();
- uint64_t current_snap_id = from_snap_id;
- uint64_t next_snap_id = to_snap_id;
- BitVector<2> prev_object_map;
- bool prev_object_map_valid = false;
- while (true) {
- uint64_t current_size = m_image_ctx.size;
- if (current_snap_id != CEPH_NOSNAP) {
- std::map<librados::snap_t, SnapInfo>::const_iterator snap_it =
- m_image_ctx.snap_info.find(current_snap_id);
- ceph_assert(snap_it != m_image_ctx.snap_info.end());
- current_size = snap_it->second.size;
-
- ++snap_it;
- if (snap_it != m_image_ctx.snap_info.end()) {
- next_snap_id = snap_it->first;
- } else {
- next_snap_id = CEPH_NOSNAP;
- }
- }
-
- uint64_t flags;
- int r = m_image_ctx.get_flags(from_snap_id, &flags);
- if (r < 0) {
- lderr(cct) << "diff_object_map: failed to retrieve image flags" << dendl;
- return r;
- }
- if ((flags & RBD_FLAG_FAST_DIFF_INVALID) != 0) {
- ldout(cct, 1) << "diff_object_map: cannot perform fast diff on invalid "
- << "object map" << dendl;
- return -EINVAL;
- }
-
- BitVector<2> object_map;
- std::string oid(ObjectMap<>::object_map_name(m_image_ctx.id,
- current_snap_id));
- r = cls_client::object_map_load(&m_image_ctx.md_ctx, oid, &object_map);
- if (r < 0) {
- lderr(cct) << "diff_object_map: failed to load object map " << oid
- << dendl;
- return r;
- }
- ldout(cct, 20) << "diff_object_map: loaded object map " << oid << dendl;
-
- uint64_t num_objs = Striper::get_num_objects(m_image_ctx.layout,
- current_size);
- if (object_map.size() < num_objs) {
- ldout(cct, 1) << "diff_object_map: object map too small: "
- << object_map.size() << " < " << num_objs << dendl;
- return -EINVAL;
- }
- object_map.resize(num_objs);
- object_diff_state->resize(object_map.size());
-
- uint64_t overlap = std::min(object_map.size(), prev_object_map.size());
- auto it = object_map.begin();
- auto overlap_end_it = it + overlap;
- auto pre_it = prev_object_map.begin();
- auto diff_it = object_diff_state->begin();
- uint64_t i = 0;
- for (; it != overlap_end_it; ++it, ++pre_it, ++diff_it, ++i) {
- ldout(cct, 20) << __func__ << ": object state: " << i << " "
- << static_cast<uint32_t>(*pre_it)
- << "->" << static_cast<uint32_t>(*it) << dendl;
- if (*it == OBJECT_NONEXISTENT) {
- if (*pre_it != OBJECT_NONEXISTENT) {
- *diff_it = OBJECT_DIFF_STATE_HOLE;
- }
- } else if (*it == OBJECT_EXISTS ||
- (*pre_it != *it &&
- !(*pre_it == OBJECT_EXISTS &&
- *it == OBJECT_EXISTS_CLEAN))) {
- *diff_it = OBJECT_DIFF_STATE_UPDATED;
- }
- }
- ldout(cct, 20) << "diff_object_map: computed overlap diffs" << dendl;
- auto end_it = object_map.end();
- if (object_map.size() > prev_object_map.size() &&
- (diff_from_start || prev_object_map_valid)) {
- for (; it != end_it; ++it,++diff_it, ++i) {
- ldout(cct, 20) << __func__ << ": object state: " << i << " "
- << "->" << static_cast<uint32_t>(*it) << dendl;
- if (*it == OBJECT_NONEXISTENT) {
- *diff_it = OBJECT_DIFF_STATE_NONE;
- } else {
- *diff_it = OBJECT_DIFF_STATE_UPDATED;
- }
- }
- }
- ldout(cct, 20) << "diff_object_map: computed resize diffs" << dendl;
-
- if (current_snap_id == next_snap_id || next_snap_id > to_snap_id) {
- break;
- }
- current_snap_id = next_snap_id;
- prev_object_map = object_map;
- prev_object_map_valid = true;
- }
- return 0;
-}
-
} // namespace api
} // namespace librbd