diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index 10b0231c071..564f3437f0b 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -494,6 +494,28 @@ namespace librbd { return ((snap_flags & test_flags) == test_flags); } + int ImageCtx::update_flags(snap_t in_snap_id, uint64_t flag, bool enabled) + { + assert(snap_lock.is_wlocked()); + uint64_t *_flags; + if (in_snap_id == CEPH_NOSNAP) { + _flags = &flags; + } else { + map<snap_t, SnapInfo>::iterator it = snap_info.find(in_snap_id); + if (it == snap_info.end()) { + return -ENOENT; + } + _flags = &it->second.flags; + } + + if (enabled) { + (*_flags) |= flag; + } else { + (*_flags) &= ~flag; + } + return 0; + } + const parent_info* ImageCtx::get_parent_info(snap_t in_snap_id) const { assert(snap_lock.is_locked()); diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 7cb6e3a00c6..22f3b804499 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -174,6 +174,7 @@ namespace librbd { bool test_features(uint64_t test_features) const; int get_flags(librados::snap_t in_snap_id, uint64_t *flags) const; bool test_flags(uint64_t test_flags) const; + int update_flags(librados::snap_t in_snap_id, uint64_t flag, bool enabled); const parent_info* get_parent_info(librados::snap_t in_snap_id) const; int64_t get_parent_pool_id(librados::snap_t in_snap_id) const; diff --git a/src/librbd/ObjectMap.cc b/src/librbd/ObjectMap.cc index e13f62fc993..8099a910384 100644 --- a/src/librbd/ObjectMap.cc +++ b/src/librbd/ObjectMap.cc @@ -335,10 +335,12 @@ void ObjectMap::invalidate() { CephContext *cct = m_image_ctx.cct; lderr(cct) << &m_image_ctx << " invalidating object map" << dendl; - m_image_ctx.flags |= RBD_FLAG_OBJECT_MAP_INVALID; + m_image_ctx.update_flags(m_image_ctx.snap_id, RBD_FLAG_OBJECT_MAP_INVALID, + true); librados::ObjectWriteOperation op; - cls_client::set_flags(&op, m_image_ctx.flags, RBD_FLAG_OBJECT_MAP_INVALID); + cls_client::set_flags(&op, m_image_ctx.snap_id, m_image_ctx.flags, + RBD_FLAG_OBJECT_MAP_INVALID); int r = m_image_ctx.md_ctx.operate(m_image_ctx.header_oid, &op); if (r < 0) { @@ -393,12 +395,16 @@ bool ObjectMap::Request::invalidate() { CephContext *cct = m_image_ctx.cct; RWLock::WLocker snap_locker(m_image_ctx.snap_lock); + // requests shouldn't be running while using snapshots + assert(m_image_ctx.snap_id == CEPH_NOSNAP); + lderr(cct) << &m_image_ctx << " invalidating object map" << dendl; m_state = STATE_INVALIDATE; m_image_ctx.flags |= RBD_FLAG_OBJECT_MAP_INVALID; librados::ObjectWriteOperation op; - cls_client::set_flags(&op, m_image_ctx.flags, RBD_FLAG_OBJECT_MAP_INVALID); + cls_client::set_flags(&op, CEPH_NOSNAP, m_image_ctx.flags, + RBD_FLAG_OBJECT_MAP_INVALID); librados::AioCompletion *rados_completion = create_callback_completion(); int r = m_image_ctx.md_ctx.aio_operate(m_image_ctx.header_oid,