if (r == -EINVAL) {
// object map is corrupt on-disk -- clear it and properly size it
// so future IO can keep the object map in sync
- invalidate(snap_id);
+ invalidate(snap_id, false);
librados::ObjectWriteOperation op;
if (snap_id == CEPH_NOSNAP) {
if (r < 0) {
lderr(cct) << "error refreshing object map: " << cpp_strerror(r)
<< dendl;
- invalidate(snap_id);
+ invalidate(snap_id, false);
m_object_map.clear();
return;
}
if (m_object_map.size() < num_objs) {
lderr(cct) << "object map smaller than current object count: "
<< m_object_map.size() << " != " << num_objs << dendl;
- invalidate(snap_id);
+ invalidate(snap_id, false);
// correct the size issue so future IO can keep the object map in sync
librados::ObjectWriteOperation op;
if (r < 0) {
lderr(cct) << "unable to load snapshot object map '" << snap_oid << "': "
<< cpp_strerror(r) << dendl;
- invalidate(snap_id);
+ invalidate(snap_id, false);
return;
}
if (r < 0) {
lderr(cct) << "unable to rollback object map: " << cpp_strerror(r)
<< dendl;
- invalidate(CEPH_NOSNAP);
+ invalidate(CEPH_NOSNAP, true);
}
}
if (r < 0) {
lderr(cct) << "unable to load object map: " << cpp_strerror(r)
<< dendl;
- invalidate(CEPH_NOSNAP);
+ invalidate(CEPH_NOSNAP, false);
return;
}
if (r < 0) {
lderr(cct) << "unable to snapshot object map '" << snap_oid << "': "
<< cpp_strerror(r) << dendl;
- invalidate(snap_id);
+ invalidate(snap_id, false);
return;
}
if (r < 0) {
lderr(cct) << "unable to snapshot object map: " << cpp_strerror(r)
<< dendl;
- invalidate(CEPH_NOSNAP);
+ invalidate(CEPH_NOSNAP, true);
return;
}
uint64_t flags;
m_image_ctx.get_flags(snap_id, &flags);
if ((flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0) {
- invalidate(next_snap_id);
+ invalidate(next_snap_id, true);
r = -EINVAL;
}
}
if (r < 0) {
lderr(cct) << "unable to remove object map snapshot: "
<< cpp_strerror(r) << dendl;
- invalidate(next_snap_id);
+ invalidate(next_snap_id, true);
}
}
req->send();
}
-void ObjectMap::invalidate(uint64_t snap_id) {
+void ObjectMap::invalidate(uint64_t snap_id, bool force) {
assert(m_image_ctx.snap_lock.is_wlocked());
assert(m_image_ctx.object_map_lock.is_wlocked());
uint64_t flags;
}
librados::ObjectWriteOperation op;
- if (snap_id == CEPH_NOSNAP) {
+ if (snap_id == CEPH_NOSNAP && !force) {
m_image_ctx.image_watcher->assert_header_locked(&op);
}
cls_client::set_flags(&op, snap_id, flags, flags);
case STATE_REQUEST:
if (r == -EBUSY) {
lderr(cct) << "object map lock not owned by client" << dendl;
- return true;
+ return invalidate();
} else if (r < 0) {
lderr(cct) << "failed to update object map: " << cpp_strerror(r)
<< dendl;
m_image_ctx.flags |= flags;
librados::ObjectWriteOperation op;
- m_image_ctx.image_watcher->assert_header_locked(&op);
cls_client::set_flags(&op, CEPH_NOSNAP, flags, flags);
librados::AioCompletion *rados_completion = create_callback_completion();