| 14639 | }; |
| 14640 | |
| 14641 | void MDCache::file_blockdiff(CInode *in1, CInode *in2, BlockDiff *block_diff, uint64_t max_objects, |
| 14642 | MDSContext *ctx) { |
| 14643 | ceph_assert(in1->last <= in2->last); |
| 14644 | |
| 14645 | // I think this is not required since the MDS disallows setting |
| 14646 | // layout when truncate_seq > 1. |
| 14647 | if (in1->get_inode()->layout != in2->get_inode()->layout) { |
| 14648 | dout(20) << __func__ << ": snaps have different layout: " << in1->get_inode()->layout |
| 14649 | << " vs " << in2->get_inode()->layout << dendl; |
| 14650 | block_diff->blocks.union_insert(0, in2->get_inode()->size); |
| 14651 | ctx->complete(0); |
| 14652 | return; |
| 14653 | } |
| 14654 | |
| 14655 | uint64_t scan_idx = block_diff->scan_idx; |
| 14656 | uint64_t num_objects1 = Striper::get_num_objects(in1->get_inode()->layout, |
| 14657 | in1->get_inode()->size); |
| 14658 | uint64_t num_objects2 = Striper::get_num_objects(in2->get_inode()->layout, |
| 14659 | in2->get_inode()->size); |
| 14660 | uint64_t num_objects_pending1 = num_objects1 - scan_idx; |
| 14661 | uint64_t num_objects_pending2 = num_objects2 - scan_idx; |
| 14662 | |
| 14663 | uint64_t scans = std::min( |
| 14664 | std::min(num_objects_pending1, num_objects_pending2), |
| 14665 | std::min((uint64_t)(g_conf().get_val<uint64_t>("mds_file_blockdiff_max_concurrent_object_scans")), |
| 14666 | max_objects)); |
| 14667 | |
| 14668 | dout(20) << __func__ << ": scanning " << scans << " objects" << dendl; |
| 14669 | if (scans == 0) { |
| 14670 | // we ran out of objects to scan - figure which ones |
| 14671 | if (num_objects_pending1 == 0 && num_objects_pending2 == 0) { |
| 14672 | // easy - both snaps have same number of objects |
| 14673 | dout(20) << __func__ << ": equal extent" << dendl; |
| 14674 | ctx->complete(0); |
| 14675 | } else { |
| 14676 | if (num_objects_pending1 == 0) { |
| 14677 | // first snapshot has lesser number of objects - return |
| 14678 | // an extent covering EOF. |
| 14679 | dout(20) << __func__ << ": EOF extent" << dendl; |
| 14680 | uint64_t offset = Striper::get_file_offset(g_ceph_context, &(in2->get_inode()->layout), |
| 14681 | scan_idx, 0); |
| 14682 | block_diff->blocks.union_insert(offset, in2->get_inode()->size - offset); |
| 14683 | ctx->complete(0); |
| 14684 | } else { |
| 14685 | // num_objects_pending2 == 0 |
| 14686 | dout(20) << __func__ << ": truncated extent" << dendl; |
| 14687 | ctx->complete(0); |
| 14688 | } |
| 14689 | } |
| 14690 | |
| 14691 | return; |
| 14692 | } |
| 14693 | |
| 14694 | C_ListSnapsAggregator *on_finish = new C_ListSnapsAggregator(mds, in1, in2, block_diff, ctx); |
| 14695 | MDSGatherBuilder gather_ctx(g_ceph_context, on_finish); |
| 14696 | |
| 14697 | while (scans > 0) { |
| 14698 | ObjectOperation op; |
no test coverage detected