template <typename I>
ceph::BitVector<2u>::Reference ObjectMap<I>::operator[](uint64_t object_no)
{
- assert(m_image_ctx.object_map_lock.is_wlocked());
- assert(object_no < m_object_map.size());
+ ceph_assert(m_image_ctx.object_map_lock.is_wlocked());
+ ceph_assert(object_no < m_object_map.size());
return m_object_map[object_no];
}
template <typename I>
uint8_t ObjectMap<I>::operator[](uint64_t object_no) const
{
- assert(m_image_ctx.object_map_lock.is_locked());
- assert(object_no < m_object_map.size());
+ ceph_assert(m_image_ctx.object_map_lock.is_locked());
+ ceph_assert(object_no < m_object_map.size());
return m_object_map[object_no];
}
template <typename I>
bool ObjectMap<I>::object_may_exist(uint64_t object_no) const
{
- assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
// Fall back to default logic if object map is disabled or invalid
if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
return exists;
}
+template <typename I>
+bool ObjectMap<I>::object_may_not_exist(uint64_t object_no) const
+{
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+
+ // Fall back to default logic if object map is disabled or invalid
+ if (!m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
+ m_image_ctx.snap_lock)) {
+ return true;
+ }
+
+ bool flags_set;
+ int r = m_image_ctx.test_flags(m_image_ctx.snap_id,
+ RBD_FLAG_OBJECT_MAP_INVALID,
+ m_image_ctx.snap_lock, &flags_set);
+ if (r < 0 || flags_set) {
+ return true;
+ }
+
+ RWLock::RLocker l(m_image_ctx.object_map_lock);
+ uint8_t state = (*this)[object_no];
+ bool nonexistent = (state != OBJECT_EXISTS && state != OBJECT_EXISTS_CLEAN);
+ ldout(m_image_ctx.cct, 20) << "object_no=" << object_no << " r="
+ << nonexistent << dendl;
+ return nonexistent;
+}
+
template <typename I>
bool ObjectMap<I>::update_required(const ceph::BitVector<2>::Iterator& it,
uint8_t new_state) {
- assert(m_image_ctx.object_map_lock.is_wlocked());
+ ceph_assert(m_image_ctx.object_map_lock.is_wlocked());
uint8_t state = *it;
if ((state == new_state) ||
(new_state == OBJECT_PENDING && state == OBJECT_NONEXISTENT) ||
template <typename I>
bool ObjectMap<I>::set_object_map(ceph::BitVector<2> &target_object_map) {
- assert(m_image_ctx.owner_lock.is_locked());
- assert(m_image_ctx.snap_lock.is_locked());
- assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
- m_image_ctx.snap_lock));
+ ceph_assert(m_image_ctx.owner_lock.is_locked());
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
+ m_image_ctx.snap_lock));
RWLock::RLocker object_map_locker(m_image_ctx.object_map_lock);
m_object_map = target_object_map;
return true;
template <typename I>
void ObjectMap<I>::rollback(uint64_t snap_id, Context *on_finish) {
- assert(m_image_ctx.snap_lock.is_locked());
- assert(m_image_ctx.object_map_lock.is_wlocked());
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert(m_image_ctx.object_map_lock.is_wlocked());
object_map::SnapshotRollbackRequest *req =
new object_map::SnapshotRollbackRequest(m_image_ctx, snap_id, on_finish);
template <typename I>
void ObjectMap<I>::snapshot_add(uint64_t snap_id, Context *on_finish) {
- assert(m_image_ctx.snap_lock.is_locked());
- assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
- assert(snap_id != CEPH_NOSNAP);
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
+ ceph_assert(snap_id != CEPH_NOSNAP);
object_map::SnapshotCreateRequest *req =
new object_map::SnapshotCreateRequest(m_image_ctx, &m_object_map, snap_id,
template <typename I>
void ObjectMap<I>::snapshot_remove(uint64_t snap_id, Context *on_finish) {
- assert(m_image_ctx.snap_lock.is_wlocked());
- assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
- assert(snap_id != CEPH_NOSNAP);
+ ceph_assert(m_image_ctx.snap_lock.is_wlocked());
+ ceph_assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
+ ceph_assert(snap_id != CEPH_NOSNAP);
object_map::SnapshotRemoveRequest *req =
new object_map::SnapshotRemoveRequest(m_image_ctx, &m_object_map, snap_id,
template <typename I>
void ObjectMap<I>::aio_save(Context *on_finish) {
- assert(m_image_ctx.owner_lock.is_locked());
- assert(m_image_ctx.snap_lock.is_locked());
- assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
- m_image_ctx.snap_lock));
+ ceph_assert(m_image_ctx.owner_lock.is_locked());
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
+ m_image_ctx.snap_lock));
RWLock::RLocker object_map_locker(m_image_ctx.object_map_lock);
librados::ObjectWriteOperation op;
librados::AioCompletion *comp = util::create_rados_callback(on_finish);
int r = m_image_ctx.md_ctx.aio_operate(oid, comp, &op);
- assert(r == 0);
+ ceph_assert(r == 0);
comp->release();
}
template <typename I>
void ObjectMap<I>::aio_resize(uint64_t new_size, uint8_t default_object_state,
Context *on_finish) {
- assert(m_image_ctx.owner_lock.is_locked());
- assert(m_image_ctx.snap_lock.is_locked());
- assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
- m_image_ctx.snap_lock));
- assert(m_image_ctx.image_watcher != NULL);
- assert(m_image_ctx.exclusive_lock == nullptr ||
- m_image_ctx.exclusive_lock->is_lock_owner());
+ ceph_assert(m_image_ctx.owner_lock.is_locked());
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert(m_image_ctx.test_features(RBD_FEATURE_OBJECT_MAP,
+ m_image_ctx.snap_lock));
+ ceph_assert(m_image_ctx.image_watcher != NULL);
+ ceph_assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
object_map::ResizeRequest *req = new object_map::ResizeRequest(
m_image_ctx, &m_object_map, m_snap_id, new_size, default_object_state,
CephContext *cct = m_image_ctx.cct;
ldout(cct, 20) << dendl;
- assert(m_image_ctx.snap_lock.is_locked());
- assert(m_image_ctx.object_map_lock.is_wlocked());
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert(m_image_ctx.object_map_lock.is_wlocked());
BlockGuardCell *cell;
int r = m_update_guard->detain({op.start_object_no, op.end_object_no},
const boost::optional<uint8_t> ¤t_state,
const ZTracer::Trace &parent_trace,
bool ignore_enoent, Context *on_finish) {
- assert(m_image_ctx.snap_lock.is_locked());
- assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
- assert(m_image_ctx.image_watcher != nullptr);
- assert(m_image_ctx.exclusive_lock == nullptr ||
- m_image_ctx.exclusive_lock->is_lock_owner());
- assert(snap_id != CEPH_NOSNAP ||
- m_image_ctx.object_map_lock.is_wlocked());
- assert(start_object_no < end_object_no);
+ ceph_assert(m_image_ctx.snap_lock.is_locked());
+ ceph_assert((m_image_ctx.features & RBD_FEATURE_OBJECT_MAP) != 0);
+ ceph_assert(m_image_ctx.image_watcher != nullptr);
+ ceph_assert(m_image_ctx.exclusive_lock == nullptr ||
+ m_image_ctx.exclusive_lock->is_lock_owner());
+ ceph_assert(snap_id != CEPH_NOSNAP ||
+ m_image_ctx.object_map_lock.is_wlocked());
+ ceph_assert(start_object_no < end_object_no);
CephContext *cct = m_image_ctx.cct;
ldout(cct, 20) << "start=" << start_object_no << ", "
stringify(static_cast<uint32_t>(*current_state)) : "")
<< "->" << static_cast<uint32_t>(new_state) << dendl;
if (snap_id == CEPH_NOSNAP) {
- if (end_object_no > m_object_map.size()) {
+ end_object_no = std::min(end_object_no, m_object_map.size());
+ if (start_object_no >= end_object_no) {
ldout(cct, 20) << "skipping update of invalid object map" << dendl;
m_image_ctx.op_work_queue->queue(on_finish, 0);
return;