template <typename I>
bool ObjectRequest<I>::compute_parent_extents(Extents *parent_extents,
+ ImageArea *area,
bool read_request) {
ceph_assert(ceph_mutex_is_locked(m_ictx->image_lock));
m_has_parent = false;
parent_extents->clear();
+ *area = ImageArea::DATA;
- uint64_t parent_overlap;
+ uint64_t raw_overlap;
int r = m_ictx->get_parent_overlap(
- m_io_context->read_snap().value_or(CEPH_NOSNAP), &parent_overlap);
+ m_io_context->read_snap().value_or(CEPH_NOSNAP), &raw_overlap);
if (r < 0) {
// NOTE: it's possible for a snapshot to be deleted while we are
// still reading from it
<< cpp_strerror(r) << dendl;
return false;
}
-
- if (!read_request && !m_ictx->migration_info.empty()) {
- parent_overlap = m_ictx->migration_info.overlap;
+ bool migration_write = !read_request && !m_ictx->migration_info.empty();
+ if (migration_write) {
+ raw_overlap = m_ictx->migration_info.overlap;
}
-
- if (parent_overlap == 0) {
+ if (raw_overlap == 0) {
return false;
}
- io::util::extent_to_file(m_ictx, m_object_no, 0, m_ictx->layout.object_size,
- *parent_extents);
- uint64_t object_overlap = m_ictx->prune_parent_extents(*parent_extents,
- parent_overlap);
+ std::tie(*parent_extents, *area) = io::util::object_to_area_extents(
+ m_ictx, m_object_no, {{0, m_ictx->layout.object_size}});
+ uint64_t object_overlap = m_ictx->prune_parent_extents(
+ *parent_extents, *area, raw_overlap, migration_write);
if (object_overlap > 0) {
- ldout(m_ictx->cct, 20) << "overlap " << parent_overlap << " "
- << "extents " << *parent_extents << dendl;
- m_has_parent = !parent_extents->empty();
+ m_has_parent = true;
return true;
}
return false;
image_ctx->owner_lock.lock_shared();
image_ctx->image_lock.lock_shared();
Extents parent_extents;
- if (!this->compute_parent_extents(&parent_extents, true) ||
+ ImageArea area;
+ if (!this->compute_parent_extents(&parent_extents, &area, true) ||
(image_ctx->exclusive_lock != nullptr &&
!image_ctx->exclusive_lock->is_lock_owner())) {
image_ctx->image_lock.unlock_shared();
if (it == image_ctx->copyup_list.end()) {
// create and kick off a CopyupRequest
auto new_req = CopyupRequest<I>::create(
- image_ctx, this->m_object_no, std::move(parent_extents), this->m_trace);
+ image_ctx, this->m_object_no, std::move(parent_extents), area,
+ this->m_trace);
image_ctx->copyup_list[this->m_object_no] = new_req;
image_ctx->copyup_list_lock.unlock();
I *image_ctx = this->m_ictx;
std::shared_lock image_locker{image_ctx->image_lock};
- this->compute_parent_extents(&m_parent_extents, false);
+ this->compute_parent_extents(&m_parent_extents, &m_image_area, false);
if (!this->has_parent() ||
(m_full_object &&
auto it = image_ctx->copyup_list.find(this->m_object_no);
if (it == image_ctx->copyup_list.end()) {
auto new_req = CopyupRequest<I>::create(
- image_ctx, this->m_object_no, std::move(this->m_parent_extents),
- this->m_trace);
+ image_ctx, this->m_object_no, std::move(this->m_parent_extents),
+ m_image_area, this->m_trace);
this->m_parent_extents.clear();
// make sure to wait on this CopyupRequest
int ObjectCompareAndWriteRequest<I>::filter_write_result(int r) const {
if (r <= -MAX_ERRNO) {
I *image_ctx = this->m_ictx;
- Extents image_extents;
// object extent compare mismatch
uint64_t offset = -MAX_ERRNO - r;
- io::util::extent_to_file(image_ctx, this->m_object_no, offset,
- this->m_object_len, image_extents);
+ auto [image_extents, _] = io::util::object_to_area_extents(
+ image_ctx, this->m_object_no, {{offset, this->m_object_len}});
ceph_assert(image_extents.size() == 1);
if (m_mismatch_offset) {
return;
}
- // calculate reverse mapping onto the parent image
- Extents parent_image_extents;
- for (auto [object_off, object_len]: m_object_extents) {
- io::util::extent_to_file(image_ctx, this->m_object_no, object_off,
- object_len, parent_image_extents);
- }
-
- uint64_t parent_overlap = 0;
+ Extents parent_extents;
+ uint64_t raw_overlap = 0;
uint64_t object_overlap = 0;
- int r = image_ctx->get_parent_overlap(snap_id_end, &parent_overlap);
- if (r == 0) {
- object_overlap = image_ctx->prune_parent_extents(parent_image_extents,
- parent_overlap);
+ image_ctx->get_parent_overlap(snap_id_end, &raw_overlap);
+ if (raw_overlap > 0) {
+ // calculate reverse mapping onto the parent image
+ std::tie(parent_extents, m_image_area) = io::util::object_to_area_extents(
+ image_ctx, this->m_object_no, m_object_extents);
+ object_overlap = image_ctx->prune_parent_extents(
+ parent_extents, m_image_area, raw_overlap, false);
}
-
if (object_overlap == 0) {
image_locker.unlock();
&ObjectListSnapsRequest<I>::handle_list_from_parent>(this);
auto aio_comp = AioCompletion::create_and_start(
ctx, librbd::util::get_image_ctx(image_ctx->parent), AIO_TYPE_GENERIC);
- ldout(cct, 20) << "aio_comp=" << aio_comp<< ", "
- << "parent_image_extents " << parent_image_extents << dendl;
+ ldout(cct, 20) << "completion=" << aio_comp
+ << " parent_extents=" << parent_extents
+ << " area=" << m_image_area << dendl;
auto list_snaps_flags = (
m_list_snaps_flags | LIST_SNAPS_FLAG_IGNORE_ZEROED_EXTENTS);
ImageListSnapsRequest<I> req(
- *image_ctx->parent, aio_comp, std::move(parent_image_extents),
+ *image_ctx->parent, aio_comp, std::move(parent_extents), m_image_area,
{0, image_ctx->parent->snap_id}, list_snaps_flags, &m_parent_snapshot_delta,
this->m_trace);
req.send();
// map image-extents back to this object
striper::LightweightObjectExtents object_extents;
- io::util::file_to_extents(image_ctx, image_extent.get_off(),
- image_extent.get_len(), 0, &object_extents);
+ io::util::area_to_object_extents(image_ctx, image_extent.get_off(),
+ image_extent.get_len(), m_image_area, 0,
+ &object_extents);
for (auto& object_extent : object_extents) {
ceph_assert(object_extent.object_no == this->m_object_no);
intervals.insert(