coll->get_cid(), ghobject_t{os.oi.soid}, 0, bl.length(),
bl, flags);
update_size_and_usage(
- delta_stats, os.oi, 0,
+ delta_stats,
+ osd_op_params.modified_ranges,
+ os.oi, 0,
bl.length(), true);
osd_op_params.clean_regions.mark_data_region_dirty(
0,
coll->get_cid(),
ghobject_t{os.oi.soid}, offset);
if (os.oi.size > offset) {
- // TODO: modified_ranges.union_of(trim);
+ interval_set<uint64_t> trim;
+ trim.insert(offset, os.oi.size - offset);
+ osd_op_params.modified_ranges.union_of(trim);
osd_op_params.clean_regions.mark_data_region_dirty(
offset,
os.oi.size - offset);
}
void PGBackend::update_size_and_usage(object_stat_sum_t& delta_stats,
+ interval_set<uint64_t>& modified,
object_info_t& oi, uint64_t offset,
uint64_t length, bool write_full)
{
+ interval_set<uint64_t> ch;
+ if (write_full) {
+ if (oi.size) {
+ ch.insert(0, oi.size);
+ } else if (length) {
+ ch.insert(offset, length);
+ }
+ modified.union_of(ch);
+ }
if (write_full ||
(offset + length > oi.size && length)) {
uint64_t new_size = offset + length;
ghobject_t{os.oi.soid}, op.extent.truncate_size);
if (op.extent.truncate_size != os.oi.size) {
os.oi.size = length;
- if (op.extent.truncate_size > os.oi.size) {
- osd_op_params.clean_regions.mark_data_region_dirty(os.oi.size,
- op.extent.truncate_size - os.oi.size);
- } else {
- osd_op_params.clean_regions.mark_data_region_dirty(op.extent.truncate_size,
- os.oi.size - op.extent.truncate_size);
+ if (op.extent.truncate_size < os.oi.size) {
+ interval_set<uint64_t> trim;
+ trim.insert(op.extent.truncate_size,
+ os.oi.size - op.extent.truncate_size);
+ osd_op_params.modified_ranges.union_of(trim);
+ osd_op_params.clean_regions.mark_data_region_dirty(
+ op.extent.truncate_size, os.oi.size - op.extent.truncate_size);
+ os.oi.clear_data_digest();
}
}
truncate_update_size_and_usage(delta_stats, os.oi, op.extent.truncate_size);
} else {
txn.write(coll->get_cid(), ghobject_t{os.oi.soid},
offset, length, std::move(buf), op.flags);
- update_size_and_usage(delta_stats, os.oi, offset, length);
+ update_size_and_usage(delta_stats, osd_op_params.modified_ranges,
+ os.oi, offset, length);
}
osd_op_params.clean_regions.mark_data_region_dirty(op.extent.offset,
op.extent.length);
+ logger().debug("{} clean_regions modified", __func__);
return seastar::now();
}
txn.write(coll->get_cid(), ghobject_t{os.oi.soid},
op.writesame.offset, len,
std::move(repeated_indata), op.flags);
- update_size_and_usage(delta_stats, os.oi, op.writesame.offset, len);
+ update_size_and_usage(delta_stats, osd_op_params.modified_ranges,
+ os.oi, op.writesame.offset, len);
osd_op_params.clean_regions.mark_data_region_dirty(op.writesame.offset, len);
return seastar::now();
}
target_coid.snap = snapid;
return obc_loader.with_clone_obc_only<RWState::RWWRITE>(
head, target_coid,
- [this, &os, &txn, &delta_stats, &osd_op_params]
+ [this, &os, &txn, &delta_stats, &osd_op_params, &snapid]
(auto, auto resolved_obc) {
if (resolved_obc->obs.oi.soid.is_head()) {
// no-op: The resolved oid returned the head object
osd_op_params.clean_regions.mark_data_region_dirty(0,
std::max(os.oi.size, resolved_obc->obs.oi.size));
osd_op_params.clean_regions.mark_omap_dirty();
- // TODO: 3) Calculate clone_overlaps by following overlaps
- // forward from rollback snapshot
- // https://tracker.ceph.com/issues/58263
+
+ // 3) Calculate clone_overlaps by following overlaps
+ const auto& clone_overlap =
+ resolved_obc->ssc->snapset.clone_overlap;
+ auto iter = clone_overlap.lower_bound(snapid);
+ ceph_assert(iter != clone_overlap.end());
+ interval_set<uint64_t> overlaps = iter->second;
+ for (const auto&i: clone_overlap) {
+ overlaps.intersection_of(i.second);
+ }
+
+ if (os.oi.size > 0) {
+ interval_set<uint64_t> modified;
+ modified.insert(0, os.oi.size);
+ overlaps.intersection_of(modified);
+ modified.subtract(overlaps);
+ osd_op_params.modified_ranges.union_of(modified);
+ }
return rollback_iertr::now();
}).safe_then_interruptible([] {
logger().debug("PGBackend::rollback succefully");
// if there's no snapshot, we delete the object;
// otherwise, do nothing.
crimson::ct_error::enoent::handle(
- [this, &os, &snapid, &txn, &delta_stats, &snapc, &ss] {
+ [this, &os, &snapid, &txn, &delta_stats, &snapc, &ss, &osd_op_params] {
logger().debug("PGBackend::rollback: deleting head on {}"
" with snap_id of {}"
" because got ENOENT|whiteout on obc lookup",
os.oi.soid, snapid);
- return remove(os, txn, delta_stats, should_whiteout(ss, snapc));
+ return remove(os, txn, osd_op_params, delta_stats,
+ should_whiteout(ss, snapc), os.oi.size);
}),
rollback_ertr::pass_further{},
crimson::ct_error::assert_all{"unexpected error in rollback"}
txn.write(coll->get_cid(), ghobject_t{os.oi.soid},
os.oi.size /* offset */, op.extent.length,
std::move(osd_op.indata), op.flags);
- update_size_and_usage(delta_stats, os.oi, os.oi.size,
- op.extent.length);
+ update_size_and_usage(delta_stats,
+ osd_op_params.modified_ranges,
+ os.oi, os.oi.size, op.extent.length);
osd_op_params.clean_regions.mark_data_region_dirty(os.oi.size,
op.extent.length);
}
ghobject_t{os.oi.soid},
op.extent.offset,
op.extent.length);
- // TODO: modified_ranges.union_of(zeroed);
+ interval_set<uint64_t> ch;
+ ch.insert(op.extent.offset, op.extent.length);
+ osd_op_params.modified_ranges.union_of(ch);
osd_op_params.clean_regions.mark_data_region_dirty(op.extent.offset,
op.extent.length);
delta_stats.num_wr++;
PGBackend::remove_iertr::future<>
PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn,
- object_stat_sum_t& delta_stats, bool whiteout)
+ osd_op_params_t& osd_op_params,
+ object_stat_sum_t& delta_stats,
+ bool whiteout,
+ int num_bytes)
{
if (!os.exists) {
return crimson::ct_error::enoent::make();
}
txn.remove(coll->get_cid(),
ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
- delta_stats.num_bytes -= os.oi.size;
if (os.oi.is_omap()) {
os.oi.clear_flag(object_info_t::FLAG_OMAP);
delta_stats.num_objects_omap--;
}
+ if (os.oi.size > 0) {
+ interval_set<uint64_t> ch;
+ ch.insert(0, os.oi.size);
+ osd_op_params.modified_ranges.union_of(ch);
+ osd_op_params.clean_regions.mark_data_region_dirty(0, os.oi.size);
+ }
+
+ osd_op_params.clean_regions.mark_omap_dirty();
+ delta_stats.num_wr++;
+ // num_bytes of the removed clone or head object
+ delta_stats.num_bytes -= num_bytes;
os.oi.size = 0;
os.oi.new_object();
- // todo: clone_overlap
+ // todo: update watchers
+
if (whiteout) {
logger().debug("{} setting whiteout on {} ",__func__, os.oi.soid);
os.oi.set_flag(object_info_t::FLAG_WHITEOUT);
ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
return seastar::now();
}
- // todo: update watchers
+
+ // delete the head
+ delta_stats.num_objects--;
+ if (os.oi.soid.is_snap()) {
+ delta_stats.num_object_clones--;
+ }
if (os.oi.is_whiteout()) {
+ logger().debug("{} deleting whiteout on {}", __func__, os.oi.soid);
os.oi.clear_flag(object_info_t::FLAG_WHITEOUT);
delta_stats.num_whiteouts--;
}
- delta_stats.num_objects--;
os.exists = false;
return seastar::now();
}