journal(NULL),
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)),
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)),
const ParentImageInfo* ImageCtx::get_parent_info(snap_t in_snap_id) const
{
ceph_assert(image_lock.is_locked());
- ceph_assert(parent_lock.is_locked());
if (in_snap_id == CEPH_NOSNAP)
return &parent_md;
const SnapInfo *info = get_snap_info(in_snap_id);
/**
* Lock ordering:
*
- * owner_lock, image_lock, parent_lock,
+ * owner_lock, image_lock
* async_op_lock, timestamp_lock
*/
RWLock owner_lock; // protects exclusive lock leadership updates
// lock_tag
// lockers
// object_map
- RWLock parent_lock; // protects parent_md and parent
+ // parent_md and parent
RWLock timestamp_lock; // protects (create/access/modify)_timestamp
Mutex async_ops_lock; // protects async_ops and async_requests
}
{
- RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
+ RWLock::RLocker image_locker(m_image_ctx.image_lock);
if (m_image_ctx.parent_md.spec.pool_id == -1) {
lderr(cct) << "image has no parent" << dendl;
return -EINVAL;
}
m_image_ctx.image_lock.get_read();
- m_image_ctx.parent_lock.get_read();
// can't flatten a non-clone
if (m_image_ctx.parent_md.spec.pool_id == -1) {
lderr(cct) << "image has no parent" << dendl;
- m_image_ctx.parent_lock.put_read();
m_image_ctx.image_lock.put_read();
on_finish->complete(-EINVAL);
return;
}
if (m_image_ctx.snap_id != CEPH_NOSNAP) {
lderr(cct) << "snapshots cannot be flattened" << dendl;
- m_image_ctx.parent_lock.put_read();
m_image_ctx.image_lock.put_read();
on_finish->complete(-EROFS);
return;
uint64_t overlap_objects = Striper::get_num_objects(m_image_ctx.layout,
overlap);
- m_image_ctx.parent_lock.put_read();
m_image_ctx.image_lock.put_read();
operation::FlattenRequest<I> *req = new operation::FlattenRequest<I>(
}
{
- RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
+ RWLock::RLocker image_locker(m_image_ctx.image_lock);
if (m_image_ctx.migration_info.empty()) {
lderr(cct) << "image has no migrating parent" << dendl;
return -EINVAL;
}
m_image_ctx.image_lock.get_read();
- m_image_ctx.parent_lock.get_read();
if (m_image_ctx.migration_info.empty()) {
lderr(cct) << "image has no migrating parent" << dendl;
- m_image_ctx.parent_lock.put_read();
m_image_ctx.image_lock.put_read();
on_finish->complete(-EINVAL);
return;
}
if (m_image_ctx.snap_id != CEPH_NOSNAP) {
lderr(cct) << "snapshots cannot be migrated" << dendl;
- m_image_ctx.parent_lock.put_read();
m_image_ctx.image_lock.put_read();
on_finish->complete(-EROFS);
return;
}
- m_image_ctx.parent_lock.put_read();
m_image_ctx.image_lock.put_read();
operation::MigrateRequest<I> *req = new operation::MigrateRequest<I>(
DiffContext diff_context(m_image_ctx, m_callback, m_callback_arg,
m_whole_object, from_snap_id, end_snap_id);
if (m_include_parent && from_snap_id == 0) {
- RWLock::RLocker l(m_image_ctx.image_lock);
- RWLock::RLocker l2(m_image_ctx.parent_lock);
+ RWLock::RLocker image_locker(m_image_ctx.image_lock);
uint64_t overlap = 0;
m_image_ctx.get_parent_overlap(m_image_ctx.snap_id, &overlap);
r = 0;
}
RWLock::RLocker image_locker(ictx->image_lock);
- RWLock::RLocker parent_locker(ictx->parent_lock);
- bool release_parent_locks = false;
- BOOST_SCOPE_EXIT_ALL(ictx, &release_parent_locks) {
- if (release_parent_locks) {
- ictx->parent->parent_lock.put_read();
+ bool release_image_lock = false;
+ BOOST_SCOPE_EXIT_ALL(ictx, &release_image_lock) {
+ if (release_image_lock) {
ictx->parent->image_lock.put_read();
}
};
// of the migration source image
auto parent = ictx->parent;
if (!ictx->migration_info.empty() && ictx->parent != nullptr) {
- release_parent_locks = true;
+ release_image_lock = true;
ictx->parent->image_lock.get_read();
- ictx->parent->parent_lock.get_read();
parent = ictx->parent->parent;
}
parent_spec.pool_id = -1;
} else {
RWLock::RLocker image_locker(src->image_lock);
- RWLock::RLocker parent_locker(src->parent_lock);
// use oldest snapshot or HEAD for parent spec
if (!src->snap_info.empty()) {
cls::rbd::ParentImageSpec parent_spec;
{
RWLock::RLocker image_locker(m_src_image_ctx->image_lock);
- RWLock::RLocker parent_locker(m_src_image_ctx->parent_lock);
size = m_src_image_ctx->size;
// use oldest snapshot or HEAD for parent spec
uint64_t parent_overlap;
{
RWLock::RLocker image_locker(child_image_ctx->image_lock);
- RWLock::RLocker parent_locker(child_image_ctx->parent_lock);
// use oldest snapshot or HEAD for parent spec
if (!child_image_ctx->snap_info.empty()) {
// is mirroring not enabled for the parent?
{
- RWLock::RLocker l(ictx->parent_lock);
+ RWLock::RLocker image_locker(ictx->image_lock);
ImageCtx *parent = ictx->parent;
if (parent) {
if (relax_same_pool_parent_check &&
{
m_ictx->image_lock.get_read();
librados::snap_t snap_id = m_ictx->snap_id;
- m_ictx->parent_lock.get_read();
uint64_t overlap = 0;
m_ictx->get_parent_overlap(snap_id, &overlap);
- m_ictx->parent_lock.put_read();
m_ictx->image_lock.put_read();
uint64_t object_no = oid_to_object_no(oid.name, m_ictx->object_prefix);
template <typename I>
void ObjectCopyRequest<I>::send_read_from_parent() {
m_src_image_ctx->image_lock.get_read();
- m_src_image_ctx->parent_lock.get_read();
io::Extents image_extents;
compute_read_from_parent_ops(&image_extents);
m_src_image_ctx->image_lock.put_read();
if (image_extents.empty()) {
- m_src_image_ctx->parent_lock.put_read();
handle_read_from_parent(0);
return;
}
std::move(image_extents),
io::ReadResult{&m_read_from_parent_data}, 0,
ZTracer::Trace());
- src_image_ctx->parent_lock.put_read();
}
template <typename I>
m_read_snaps = {};
m_zero_interval = {};
- m_src_image_ctx->parent_lock.get_read();
+ m_src_image_ctx->image_lock.get_read();
bool hide_parent = (m_src_image_ctx->parent != nullptr);
- m_src_image_ctx->parent_lock.put_read();
+ m_src_image_ctx->image_lock.put_read();
librados::snap_t src_copy_point_snap_id = m_snap_map.rbegin()->first;
bool prev_exists = hide_parent;
void ObjectCopyRequest<I>::compute_read_from_parent_ops(
io::Extents *parent_image_extents) {
assert(m_src_image_ctx->image_lock.is_locked());
- assert(m_src_image_ctx->parent_lock.is_locked());
m_read_ops = {};
m_zero_interval = {};
bool fast_diff = m_dst_image_ctx->test_features(RBD_FEATURE_FAST_DIFF);
uint64_t prev_end_size = 0;
- m_src_image_ctx->parent_lock.get_read();
+ m_src_image_ctx->image_lock.get_read();
bool hide_parent = (m_src_image_ctx->parent != nullptr);
- m_src_image_ctx->parent_lock.put_read();
+ m_src_image_ctx->image_lock.put_read();
for (auto &it : m_dst_zero_interval) {
auto src_snap_seq = it.first;
if (hide_parent) {
RWLock::RLocker image_locker(m_dst_image_ctx->image_lock);
- RWLock::RLocker parent_locker(m_dst_image_ctx->parent_lock);
uint64_t parent_overlap = 0;
- int r = m_dst_image_ctx->get_parent_overlap(dst_snap_seq, &parent_overlap);
+ int r = m_dst_image_ctx->get_parent_overlap(dst_snap_seq,
+ &parent_overlap);
if (r < 0) {
ldout(m_cct, 5) << "failed getting parent overlap for snap_id: "
<< dst_snap_seq << ": " << cpp_strerror(r) << dendl;
// adjust in-memory image size now that it's updated on disk
RWLock::WLocker image_locker(m_image_ctx->image_lock);
if (m_image_ctx->size > m_size) {
- RWLock::WLocker parent_locker(m_image_ctx->parent_lock);
if (m_image_ctx->parent_md.spec.pool_id != -1 &&
m_image_ctx->parent_md.overlap > m_size) {
m_image_ctx->parent_md.overlap = m_size;
template <typename I>
void SetHeadRequest<I>::send_detach_parent() {
- m_image_ctx->parent_lock.get_read();
+ m_image_ctx->image_lock.get_read();
if (m_image_ctx->parent_md.spec.pool_id == -1 ||
(m_image_ctx->parent_md.spec == m_parent_spec &&
m_image_ctx->parent_md.overlap == m_parent_overlap)) {
- m_image_ctx->parent_lock.put_read();
+ m_image_ctx->image_lock.put_read();
send_attach_parent();
return;
}
- m_image_ctx->parent_lock.put_read();
+ m_image_ctx->image_lock.put_read();
ldout(m_cct, 20) << dendl;
{
// adjust in-memory parent now that it's updated on disk
- RWLock::WLocker parent_locker(m_image_ctx->parent_lock);
+ RWLock::WLocker image_locker(m_image_ctx->image_lock);
m_image_ctx->parent_md.spec = {};
m_image_ctx->parent_md.overlap = 0;
}
template <typename I>
void SetHeadRequest<I>::send_attach_parent() {
- m_image_ctx->parent_lock.get_read();
+ m_image_ctx->image_lock.get_read();
if (m_image_ctx->parent_md.spec == m_parent_spec &&
m_image_ctx->parent_md.overlap == m_parent_overlap) {
- m_image_ctx->parent_lock.put_read();
+ m_image_ctx->image_lock.put_read();
finish(0);
return;
}
- m_image_ctx->parent_lock.put_read();
+ m_image_ctx->image_lock.put_read();
ldout(m_cct, 20) << dendl;
{
// adjust in-memory parent now that it's updated on disk
- RWLock::WLocker parent_locker(m_image_ctx->parent_lock);
+ RWLock::WLocker image_locker(m_image_ctx->image_lock);
m_image_ctx->parent_md.spec = m_parent_spec;
m_image_ctx->parent_md.overlap = m_parent_overlap;
}
void DetachChildRequest<I>::send() {
{
RWLock::RLocker image_locker(m_image_ctx.image_lock);
- RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
// use oldest snapshot or HEAD for parent spec
if (!m_image_ctx.snap_info.empty()) {
I &child_image_ctx, const ParentImageInfo &parent_md,
const MigrationInfo &migration_info) {
ceph_assert(child_image_ctx.image_lock.is_locked());
- ceph_assert(child_image_ctx.parent_lock.is_locked());
return (is_open_required(child_image_ctx, parent_md, migration_info) ||
is_close_required(child_image_ctx, parent_md, migration_info));
}
template <typename I>
void RefreshParentRequest<I>::apply() {
ceph_assert(m_child_image_ctx.image_lock.is_wlocked());
- ceph_assert(m_child_image_ctx.parent_lock.is_wlocked());
std::swap(m_child_image_ctx.parent, m_parent_image_ctx);
}
void RefreshRequest<I>::send_v2_refresh_parent() {
{
RWLock::RLocker image_locker(m_image_ctx.image_lock);
- RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
ParentImageInfo parent_md;
MigrationInfo migration_info;
RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
RWLock::WLocker image_locker(m_image_ctx.image_lock);
- RWLock::WLocker parent_locker(m_image_ctx.parent_lock);
m_image_ctx.size = m_size;
m_image_ctx.lockers = m_lockers;
bool refresh_parent;
{
RWLock::RLocker image_locker(m_image_ctx.image_lock);
- RWLock::RLocker parent_locker(m_image_ctx.parent_lock);
const auto parent_info = m_image_ctx.get_parent_info(m_snap_id);
if (parent_info == nullptr) {
RWLock::WLocker owner_locker(m_image_ctx.owner_lock);
RWLock::WLocker image_locker(m_image_ctx.image_lock);
- RWLock::WLocker parent_locker(m_image_ctx.parent_lock);
if (m_snap_id != CEPH_NOSNAP) {
ceph_assert(m_image_ctx.exclusive_lock == nullptr);
int r = m_image_ctx.snap_set(m_snap_id);
int r = ictx->state->refresh_if_required();
if (r < 0)
return r;
- RWLock::RLocker l(ictx->image_lock);
- RWLock::RLocker l2(ictx->parent_lock);
+ RWLock::RLocker image_locker(ictx->image_lock);
return ictx->get_parent_overlap(ictx->snap_id, overlap);
}
void CopyupRequest<I>::read_from_parent() {
auto cct = m_image_ctx->cct;
RWLock::RLocker image_locker(m_image_ctx->image_lock);
- RWLock::RLocker parent_locker(m_image_ctx->parent_lock);
if (m_image_ctx->parent == nullptr) {
ldout(cct, 5) << "parent detached" << dendl;
void CopyupRequest<I>::deep_copy() {
auto cct = m_image_ctx->cct;
ceph_assert(m_image_ctx->image_lock.is_locked());
- ceph_assert(m_image_ctx->parent_lock.is_locked());
ceph_assert(m_image_ctx->parent != nullptr);
m_lock.Lock();
}
}
- RWLock::RLocker parent_locker(m_image_ctx->parent_lock);
std::copy_if(m_image_ctx->snaps.rbegin(), m_image_ctx->snaps.rend(),
std::back_inserter(m_snap_ids),
[this, cct=m_image_ctx->cct, &deep_copied](uint64_t snap_id) {
bool ObjectRequest<I>::compute_parent_extents(Extents *parent_extents,
bool read_request) {
ceph_assert(m_ictx->image_lock.is_locked());
- ceph_assert(m_ictx->parent_lock.is_locked());
m_has_parent = false;
parent_extents->clear();
I *image_ctx = this->m_ictx;
RWLock::RLocker image_locker(image_ctx->image_lock);
- RWLock::RLocker parent_locker(image_ctx->parent_lock);
// calculate reverse mapping onto the image
Extents parent_extents;
}
if (object_overlap == 0) {
- parent_locker.unlock();
image_locker.unlock();
this->finish(-ENOENT);
image_ctx->owner_lock.get_read();
image_ctx->image_lock.get_read();
- image_ctx->parent_lock.get_read();
Extents parent_extents;
if (!this->compute_parent_extents(&parent_extents, true) ||
(image_ctx->exclusive_lock != nullptr &&
!image_ctx->exclusive_lock->is_lock_owner())) {
- image_ctx->parent_lock.put_read();
image_ctx->image_lock.put_read();
image_ctx->owner_lock.put_read();
this->finish(0);
image_ctx->copyup_list[this->m_object_no] = new_req;
image_ctx->copyup_list_lock.Unlock();
- image_ctx->parent_lock.put_read();
image_ctx->image_lock.put_read();
new_req->send();
} else {
image_ctx->copyup_list_lock.Unlock();
- image_ctx->parent_lock.put_read();
image_ctx->image_lock.put_read();
}
void AbstractObjectWriteRequest<I>::compute_parent_info() {
I *image_ctx = this->m_ictx;
RWLock::RLocker image_locker(image_ctx->image_lock);
- RWLock::RLocker parent_locker(image_ctx->parent_lock);
this->compute_parent_extents(&m_parent_extents, false);
// stop early if the parent went away - it just means
// another flatten finished first, so this one is useless.
- image_ctx.parent_lock.get_read();
+ image_ctx.image_lock.get_read();
if (!image_ctx.parent) {
ldout(cct, 5) << "image already flattened" << dendl;
- image_ctx.parent_lock.put_read();
+ image_ctx.image_lock.put_read();
image_ctx.owner_lock.put_read();
this->complete(0);
return;
}
- image_ctx.parent_lock.put_read();
+ image_ctx.image_lock.put_read();
// remove parent from this (base) image
auto ctx = create_context_callback<
ldout(cct, 10) << dendl;
RWLock::RLocker image_locker(image_ctx.image_lock);
- RWLock::RLocker parent_locker(image_ctx.parent_lock);
auto overlap = image_ctx.migration_info.overlap;
template <typename I>
void ResizeRequest<I>::compute_parent_overlap() {
I &image_ctx = this->m_image_ctx;
- RWLock::RLocker l2(image_ctx.parent_lock);
+ ceph_assert(image_ctx.image_lock.is_locked());
+
if (image_ctx.parent == NULL) {
m_new_parent_overlap = 0;
} else {
RWLock::WLocker image_locker(image_ctx.image_lock);
image_ctx.size = m_new_size;
- RWLock::WLocker parent_locker(image_ctx.parent_lock);
if (image_ctx.parent != NULL && m_new_size < m_original_size) {
image_ctx.parent_md.overlap = m_new_parent_overlap;
}
RWLock::RLocker owner_locker(image_ctx.owner_lock);
RWLock::RLocker image_locker(image_ctx.image_lock);
- RWLock::RLocker parent_locker(image_ctx.parent_lock);
// should have been canceled prior to releasing lock
ceph_assert(image_ctx.exclusive_lock == nullptr ||
bool detach_child = false;
{
RWLock::RLocker image_locker(image_ctx.image_lock);
- RWLock::RLocker parent_locker(image_ctx.parent_lock);
cls::rbd::ParentImageSpec our_pspec;
int r = image_ctx.get_parent_spec(m_snap_id, &our_pspec);
cls::rbd::ParentImageSpec &pspec) {
I &image_ctx = this->m_image_ctx;
ceph_assert(image_ctx.image_lock.is_locked());
- ceph_assert(image_ctx.parent_lock.is_locked());
if (pspec.pool_id != -1) {
map<uint64_t, SnapInfo>::iterator it;
return 1;
}
- RWLock::RLocker parent_locker(image_ctx.parent_lock);
uint64_t overlap_objects = 0;
uint64_t overlap;
int r = image_ctx.get_parent_overlap(CEPH_NOSNAP, &overlap);
uint64_t parent_overlap;
{
RWLock::RLocker image_locker(image_ctx.image_lock);
- RWLock::RLocker parent_locker(image_ctx.parent_lock);
snapc = image_ctx.snapc;
has_snapshots = !image_ctx.snaps.empty();
owner_lock(image_ctx.owner_lock),
image_lock(image_ctx.image_lock),
timestamp_lock(image_ctx.timestamp_lock),
- parent_lock(image_ctx.parent_lock),
async_ops_lock(image_ctx.async_ops_lock),
copyup_list_lock(image_ctx.copyup_list_lock),
order(image_ctx.order),
RWLock &owner_lock;
RWLock &image_lock;
RWLock ×tamp_lock;
- RWLock &parent_lock;
Mutex &async_ops_lock;
Mutex ©up_list_lock;
public:
void inject_snap_info(librbd::ImageCtx *ictx, uint64_t snap_id) {
RWLock::WLocker image_locker(ictx->image_lock);
- RWLock::RLocker parent_locker(ictx->parent_lock);
ictx->add_snap(cls::rbd::UserSnapshotNamespace(), "snap name", snap_id,
ictx->size, ictx->parent_md,
RBD_PROTECTION_STATUS_UNPROTECTED, 0, utime_t());