]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/ObjectMap.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / librbd / ObjectMap.cc
index db5b741909691663faf44c711de1b8c80b2fe94c..50cbfda89220edc23747aa1a8763401754ecd6f7 100644 (file)
@@ -71,23 +71,23 @@ bool ObjectMap<I>::is_compatible(const file_layout_t& layout, uint64_t size) {
 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,
@@ -111,10 +111,37 @@ bool ObjectMap<I>::object_may_exist(uint64_t object_no) const
   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) ||
@@ -144,10 +171,10 @@ void ObjectMap<I>::close(Context *on_finish) {
 
 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;
@@ -155,8 +182,8 @@ bool ObjectMap<I>::set_object_map(ceph::BitVector<2> &target_object_map) {
 
 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);
@@ -165,9 +192,9 @@ void ObjectMap<I>::rollback(uint64_t snap_id, Context *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,
@@ -177,9 +204,9 @@ void ObjectMap<I>::snapshot_add(uint64_t snap_id, Context *on_finish) {
 
 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,
@@ -189,10 +216,10 @@ void ObjectMap<I>::snapshot_remove(uint64_t snap_id, Context *on_finish) {
 
 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;
@@ -205,20 +232,20 @@ void ObjectMap<I>::aio_save(Context *on_finish) {
   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,
@@ -231,8 +258,8 @@ void ObjectMap<I>::detained_aio_update(UpdateOperation &&op) {
   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},
@@ -288,14 +315,14 @@ void ObjectMap<I>::aio_update(uint64_t snap_id, uint64_t start_object_no,
                               const boost::optional<uint8_t> &current_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 << ", "
@@ -304,7 +331,8 @@ void ObjectMap<I>::aio_update(uint64_t snap_id, uint64_t 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;