| 290 | |
| 291 | template <typename I> |
| 292 | int DiffIterate<I>::execute() { |
| 293 | CephContext* cct = m_image_ctx.cct; |
| 294 | |
| 295 | ceph_assert(m_image_ctx.data_ctx.is_valid()); |
| 296 | |
| 297 | librados::snap_t from_snap_id = m_from_snap_id; |
| 298 | librados::snap_t end_snap_id; |
| 299 | uint64_t from_size = 0; |
| 300 | uint64_t end_size; |
| 301 | { |
| 302 | std::shared_lock image_locker{m_image_ctx.image_lock}; |
| 303 | if (from_snap_id != 0) { |
| 304 | auto info = m_image_ctx.get_snap_info(from_snap_id); |
| 305 | if (info == nullptr) { |
| 306 | return -ENOENT; |
| 307 | } |
| 308 | from_size = info->size; |
| 309 | } |
| 310 | end_snap_id = m_image_ctx.snap_id; |
| 311 | end_size = m_image_ctx.get_image_size(end_snap_id); |
| 312 | } |
| 313 | |
| 314 | if (from_snap_id > end_snap_id) { |
| 315 | return -EINVAL; |
| 316 | } |
| 317 | if (from_snap_id == end_snap_id || m_length == 0) { |
| 318 | // no diff. |
| 319 | return 0; |
| 320 | } |
| 321 | |
| 322 | int r; |
| 323 | bool fast_diff_enabled = false; |
| 324 | uint64_t start_object_no, end_object_no; |
| 325 | BitVector<2> object_diff_state; |
| 326 | interval_set<uint64_t> parent_diff; |
| 327 | if (m_whole_object) { |
| 328 | std::tie(start_object_no, end_object_no) = calc_object_diff_range(); |
| 329 | |
| 330 | C_SaferCond ctx; |
| 331 | auto req = object_map::DiffRequest<I>::create(&m_image_ctx, from_snap_id, |
| 332 | end_snap_id, start_object_no, |
| 333 | end_object_no, |
| 334 | &object_diff_state, &ctx); |
| 335 | req->send(); |
| 336 | r = ctx.wait(); |
| 337 | if (r < 0) { |
| 338 | ldout(cct, 5) << "fast diff disabled" << dendl; |
| 339 | } else { |
| 340 | ldout(cct, 5) << "fast diff enabled" << dendl; |
| 341 | ceph_assert(object_diff_state.size() == end_object_no - start_object_no); |
| 342 | fast_diff_enabled = true; |
| 343 | |
| 344 | // check parent overlap only if we are comparing to the beginning of time |
| 345 | if (m_include_parent && from_snap_id == 0) { |
| 346 | std::shared_lock image_locker{m_image_ctx.image_lock}; |
| 347 | uint64_t raw_overlap = 0; |
| 348 | m_image_ctx.get_parent_overlap(m_image_ctx.snap_id, &raw_overlap); |
| 349 | io::Extents parent_extents = {{m_offset, m_length}}; |
no test coverage detected