}
// rollback the object map (copy snapshot object map to HEAD)
- RWLock::WLocker object_map_locker(m_dst_image_ctx->object_map_lock);
auto ctx = new FunctionContext([this, finish_op_ctx](int r) {
handle_copy_object_map(r);
finish_op_ctx->complete(0);
{
RWLock::WLocker image_locker(m_dst_image_ctx->image_lock);
- RWLock::WLocker object_map_locker(m_dst_image_ctx->object_map_lock);
std::swap(m_dst_image_ctx->object_map, m_object_map);
}
delete m_object_map;
owner_lock(util::unique_lock_name("librbd::ImageCtx::owner_lock", this)),
image_lock(util::unique_lock_name("librbd::ImageCtx::image_lock", this)),
parent_lock(util::unique_lock_name("librbd::ImageCtx::parent_lock", this)),
- object_map_lock(util::unique_lock_name("librbd::ImageCtx::object_map_lock", this)),
timestamp_lock(util::unique_lock_name("librbd::ImageCtx::timestamp_lock", this)),
async_ops_lock(util::unique_lock_name("librbd::ImageCtx::async_ops_lock", this)),
copyup_list_lock(util::unique_lock_name("librbd::ImageCtx::copyup_list_lock", this)),
* Lock ordering:
*
* owner_lock, image_lock, parent_lock,
- * object_map_lock, async_op_lock, timestamp_lock
+ * async_op_lock, timestamp_lock
*/
RWLock owner_lock; // protects exclusive lock leadership updates
RWLock image_lock; // protects snapshot-related member variables,
// exclusive_locked
// lock_tag
// lockers
+ // object_map
RWLock parent_lock; // protects parent_md and parent
- RWLock object_map_lock; // protects object map updates and object_map itself
RWLock timestamp_lock; // protects (create/access/modify)_timestamp
Mutex async_ops_lock; // protects async_ops and async_requests
});
auto dst_image_ctx = m_dst_image_ctx;
- dst_image_ctx->object_map_lock.get_write();
bool sent = dst_image_ctx->object_map->template aio_update<
Context, &Context::complete>(dst_snap_id, m_dst_object_number, object_state,
{}, {}, false, ctx);
// NOTE: state machine might complete before we reach here
- dst_image_ctx->object_map_lock.put_write();
dst_image_ctx->image_lock.put_read();
dst_image_ctx->owner_lock.put_read();
if (!sent) {
int update_head() {
auto& image_ctx = this->m_image_ctx;
- RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
+ ceph_assert(image_ctx.image_lock.is_locked());
+
bool sent = image_ctx.object_map->template aio_update<Context>(
CEPH_NOSNAP, m_object_no, m_head_object_map_state, {}, m_trace, false,
this);
int update_snapshot(uint64_t snap_id) {
auto& image_ctx = this->m_image_ctx;
+ ceph_assert(image_ctx.image_lock.is_locked());
+
uint8_t state = OBJECT_EXISTS;
if (image_ctx.test_features(RBD_FEATURE_FAST_DIFF, image_ctx.image_lock) &&
(m_snap_id_idx > 0 || m_first_snap_is_clean)) {
state = OBJECT_EXISTS_CLEAN;
}
- RWLock::RLocker object_map_locker(image_ctx.object_map_lock);
bool sent = image_ctx.object_map->template aio_update<Context>(
snap_id, m_object_no, state, {}, m_trace, true, this);
ceph_assert(sent);
head_object_map_state = (*r_it)->get_pre_write_object_map_state();
}
- RWLock::WLocker object_map_locker(m_image_ctx->object_map_lock);
if ((*m_image_ctx->object_map)[m_object_no] != head_object_map_state) {
// (maybe) need to update the HEAD object map state
m_snap_ids.push_back(CEPH_NOSNAP);
}
- object_map_locker.unlock();
image_locker.unlock();
ceph_assert(m_image_ctx->exclusive_lock->is_lock_owner());
ldout(image_ctx->cct, 20) << this->m_oid << " " << this->m_object_off
<< "~" << this->m_object_len << dendl;
- image_ctx->object_map_lock.get_write();
if (image_ctx->object_map->template aio_update<
AbstractObjectWriteRequest<I>,
&AbstractObjectWriteRequest<I>::handle_pre_write_object_map_update>(
CEPH_NOSNAP, this->m_object_no, new_state, {}, this->m_trace, false,
this)) {
- image_ctx->object_map_lock.put_write();
image_ctx->image_lock.put_read();
return;
}
- image_ctx->object_map_lock.put_write();
image_ctx->image_lock.put_read();
write_object();
}
// should have been flushed prior to releasing lock
ceph_assert(image_ctx->exclusive_lock->is_lock_owner());
- image_ctx->object_map_lock.get_write();
if (image_ctx->object_map->template aio_update<
AbstractObjectWriteRequest<I>,
&AbstractObjectWriteRequest<I>::handle_post_write_object_map_update>(
CEPH_NOSNAP, this->m_object_no, OBJECT_NONEXISTENT, OBJECT_PENDING,
this->m_trace, false, this)) {
- image_ctx->object_map_lock.put_write();
image_ctx->image_lock.put_read();
return;
}
- image_ctx->object_map_lock.put_write();
image_ctx->image_lock.put_read();
this->finish(0);
}
RWLock::RLocker image_locker(image_ctx.image_lock);
ceph_assert(image_ctx.object_map != nullptr);
- RWLock::WLocker l(image_ctx.object_map_lock);
uint8_t state = (*image_ctx.object_map)[m_object_no];
-
ldout(cct, 10) << "C_VerifyObjectCallback::object_map_action"
<< " object " << image_ctx.get_object_name(m_object_no)
<< " state " << (int)state
CephContext *cct = image_ctx.cct;
ldout(cct, 5) << this << " " << __func__ << dendl;
- {
- RWLock::RLocker object_map_lock(image_ctx.object_map_lock);
- image_ctx.object_map->snapshot_add(
- m_snap_id, create_context_callback<
- SnapshotCreateRequest<I>,
- &SnapshotCreateRequest<I>::handle_create_object_map>(this));
- }
+ image_ctx.object_map->snapshot_add(
+ m_snap_id, create_context_callback<
+ SnapshotCreateRequest<I>,
+ &SnapshotCreateRequest<I>::handle_create_object_map>(this));
image_ctx.image_lock.put_read();
return nullptr;
}
ceph_assert(image_ctx.owner_lock.is_locked());
{
RWLock::RLocker image_locker(image_ctx.image_lock);
- RWLock::RLocker object_map_locker(image_ctx.object_map_lock);
if (image_ctx.snap_info.find(m_snap_id) == image_ctx.snap_info.end()) {
lderr(cct) << "snapshot doesn't exist" << dendl;
this->async_complete(-ENOENT);
{
RWLock::RLocker owner_lock(image_ctx.owner_lock);
RWLock::WLocker image_locker(image_ctx.image_lock);
- RWLock::RLocker object_map_locker(image_ctx.object_map_lock);
if (image_ctx.object_map != nullptr) {
ldout(cct, 5) << dendl;
{
RWLock::RLocker owner_locker(image_ctx.owner_lock);
RWLock::RLocker image_locker(image_ctx.image_lock);
- RWLock::WLocker object_map_lock(image_ctx.object_map_lock);
if (image_ctx.object_map != nullptr) {
CephContext *cct = image_ctx.cct;
ldout(cct, 5) << this << " " << __func__ << dendl;
C_SparsifyObject<I>,
&C_SparsifyObject<I>::handle_pre_update_object_map>(this);
- image_ctx.object_map_lock.get_write();
bool sent = image_ctx.object_map->template aio_update<
Context, &Context::complete>(CEPH_NOSNAP, m_object_no, OBJECT_PENDING,
OBJECT_EXISTS, {}, false, ctx);
// NOTE: state machine might complete before we reach here
- image_ctx.object_map_lock.put_write();
image_ctx.image_lock.put_read();
image_ctx.owner_lock.put_read();
if (!sent) {
assert(image_ctx.exclusive_lock->is_lock_owner());
assert(image_ctx.object_map != nullptr);
- RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
-
sent = image_ctx.object_map->template aio_update<
Context, &Context::complete>(CEPH_NOSNAP, m_object_no,
exists ? OBJECT_EXISTS : OBJECT_NONEXISTENT,
ceph_assert(image_ctx.exclusive_lock->is_lock_owner());
- RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
CEPH_NOSNAP, m_delete_start_min, m_num_objects, OBJECT_PENDING,
OBJECT_EXISTS, {}, false, this)) {
ceph_assert(image_ctx.exclusive_lock->is_lock_owner());
- RWLock::WLocker object_map_locker(image_ctx.object_map_lock);
if (image_ctx.object_map->template aio_update<AsyncRequest<I> >(
CEPH_NOSNAP, m_delete_start_min, m_num_objects, OBJECT_NONEXISTENT,
OBJECT_PENDING, {}, false, this)) {
image_lock(image_ctx.image_lock),
timestamp_lock(image_ctx.timestamp_lock),
parent_lock(image_ctx.parent_lock),
- object_map_lock(image_ctx.object_map_lock),
async_ops_lock(image_ctx.async_ops_lock),
copyup_list_lock(image_ctx.copyup_list_lock),
order(image_ctx.order),
RWLock &image_lock;
RWLock ×tamp_lock;
RWLock &parent_lock;
- RWLock &object_map_lock;
Mutex &async_ops_lock;
Mutex ©up_list_lock;
object_map.open(&ctx);
ASSERT_EQ(0, ctx.wait());
- RWLock::WLocker object_map_locker(ictx2->object_map_lock);
+ RWLock::RLocker image_locker(ictx2->image_lock);
ASSERT_EQ(state, object_map[0]);
}
}
object_map.open(&ctx);
ASSERT_EQ(0, ctx.wait());
- RWLock::WLocker object_map_locker(ictx2->object_map_lock);
+ RWLock::RLocker image_locker(ictx2->image_lock);
ASSERT_EQ(state, object_map[0]);
}
}