Skip to content

Commit

Permalink
librados/snap_set_diff: don't assert on empty snapset
Browse files Browse the repository at this point in the history
Instead treat the diff as a full-object delta.

Signed-off-by: Mykola Golub <mgolub@suse.com>
  • Loading branch information
trociny committed Feb 28, 2018
1 parent 57ffaaa commit 2be4840
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 6 deletions.
9 changes: 8 additions & 1 deletion src/librados/snap_set_diff.cc
Expand Up @@ -17,7 +17,8 @@
void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
librados::snap_t start, librados::snap_t end,
interval_set<uint64_t> *diff, uint64_t *end_size,
bool *end_exists, librados::snap_t *clone_end_snap_id)
bool *end_exists, librados::snap_t *clone_end_snap_id,
bool *whole_object)
{
ldout(cct, 10) << "calc_snap_set_diff start " << start << " end " << end
<< ", snap_set seq " << snap_set.seq << dendl;
Expand All @@ -27,6 +28,7 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
*end_size = 0;
*end_exists = false;
*clone_end_snap_id = 0;
*whole_object = false;

for (vector<librados::clone_info_t>::const_iterator r = snap_set.clones.begin();
r != snap_set.clones.end();
Expand All @@ -38,6 +40,11 @@ void calc_snap_set_diff(CephContext *cct, const librados::snap_set_t& snap_set,
// head is valid starting from right after the last seen seq
a = snap_set.seq + 1;
b = librados::SNAP_HEAD;
} else if (r->snaps.empty()) {
ldout(cct, 1) << "clone " << r->cloneid
<< ": empty snaps, return whole object" << dendl;
*whole_object = true;
return;
} else {
a = r->snaps[0];
// note: b might be < r->cloneid if a snap has been trimmed.
Expand Down
3 changes: 2 additions & 1 deletion src/librados/snap_set_diff.h
Expand Up @@ -12,6 +12,7 @@ void calc_snap_set_diff(CephContext *cct,
const librados::snap_set_t& snap_set,
librados::snap_t start, librados::snap_t end,
interval_set<uint64_t> *diff, uint64_t *end_size,
bool *end_exists, librados::snap_t *clone_end_snap_id);
bool *end_exists, librados::snap_t *clone_end_snap_id,
bool *whole_object);

#endif
11 changes: 8 additions & 3 deletions src/librbd/api/DiffIterate.cc
Expand Up @@ -131,17 +131,22 @@ class C_DiffObject : public Context {
uint64_t end_size;
bool end_exists;
librados::snap_t clone_end_snap_id;
bool whole_object;
calc_snap_set_diff(cct, m_snap_set, m_diff_context.from_snap_id,
m_diff_context.end_snap_id, &diff, &end_size,
&end_exists, &clone_end_snap_id);
&end_exists, &clone_end_snap_id, &whole_object);
if (whole_object) {
ldout(cct, 1) << "object " << m_oid << ": need to provide full object"
<< dendl;
}
ldout(cct, 20) << " diff " << diff << " end_exists=" << end_exists
<< dendl;
if (diff.empty()) {
if (diff.empty() && !whole_object) {
if (m_diff_context.from_snap_id == 0 && !end_exists) {
compute_parent_overlap(diffs);
}
return;
} else if (m_diff_context.whole_object) {
} else if (m_diff_context.whole_object || whole_object) {
// provide the full object extents to the callback
for (vector<ObjectExtent>::iterator q = m_object_extents.begin();
q != m_object_extents.end(); ++q) {
Expand Down
17 changes: 16 additions & 1 deletion src/librbd/deep_copy/ObjectCopyRequest.cc
Expand Up @@ -190,6 +190,12 @@ template <typename I>
void ObjectCopyRequest<I>::handle_read_object(int r) {
ldout(m_cct, 20) << "r=" << r << dendl;

if (r == -ENOENT && m_read_whole_object) {
ldout(m_cct, 5) << "object missing when forced to read whole object"
<< dendl;
r = 0;
}

if (r == -ENOENT) {
m_retry_snap_set = m_snap_set;
m_retry_missing_read = true;
Expand Down Expand Up @@ -478,7 +484,16 @@ void ObjectCopyRequest<I>::compute_read_ops() {
librados::snap_t clone_end_snap_id;
calc_snap_set_diff(m_cct, m_snap_set, start_src_snap_id,
end_src_snap_id, &diff, &end_size, &exists,
&clone_end_snap_id);
&clone_end_snap_id, &m_read_whole_object);

if (m_read_whole_object) {
ldout(m_cct, 1) << "need to read full object" << dendl;
diff.insert(0, m_src_image_ctx->layout.object_size);
exists = true;
end_size = m_src_image_ctx->layout.object_size;
clone_end_snap_id = end_src_snap_id;
}

if (!exists) {
end_size = 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/librbd/deep_copy/ObjectCopyRequest.h
Expand Up @@ -142,6 +142,7 @@ class ObjectCopyRequest {
int m_snap_ret = 0;
bool m_retry_missing_read = false;
librados::snap_set_t m_retry_snap_set;
bool m_read_whole_object = false;

std::map<WriteReadSnapIds, CopyOps> m_read_ops;
std::list<WriteReadSnapIds> m_read_snaps;
Expand Down

0 comments on commit 2be4840

Please sign in to comment.