} else {
t.touch(coll, soid);
}
- write_update_size_and_usage(ctx->new_stats, oi, ssc->snapset,
+ write_update_size_and_usage(ctx->new_stats, oi, ssc->snapset, ctx->modified_ranges,
op.extent.offset, op.extent.length, true);
-
maybe_created = true;
}
break;
else
maybe_created = true;
t.write(coll, soid, op.extent.offset, op.extent.length, nbl);
- if (ssc->snapset.clones.size()) {
- snapid_t newest = *ssc->snapset.clones.rbegin();
-
- // Replace clone_overlap[newest] with an empty interval set since there
- // should no longer be any overlap
- ssc->snapset.clone_overlap.erase(newest);
- ssc->snapset.clone_overlap[newest];
+ if (ssc->snapset.clones.size() && oi.size > 0) {
+ interval_set<uint64_t> ch;
+ ch.insert(0, oi.size);
+ ctx->modified_ranges.union_of(ch);
oi.size = 0;
}
if (op.extent.length != oi.size) {
if (obs.exists) {
t.zero(coll, soid, op.extent.offset, op.extent.length);
if (ssc->snapset.clones.size()) {
- snapid_t newest = *ssc->snapset.clones.rbegin();
interval_set<uint64_t> ch;
ch.insert(op.extent.offset, op.extent.length);
- ch.intersection_of(ssc->snapset.clone_overlap[newest]);
- ssc->snapset.clone_overlap[newest].subtract(ch);
+ ctx->modified_ranges.union_of(ch);
add_interval_usage(ch, ctx->new_stats);
}
ctx->new_stats.num_wr++;
interval_set<uint64_t> trim;
if (oi.size > op.extent.offset) {
trim.insert(op.extent.offset, oi.size-op.extent.offset);
+ ctx->modified_ranges.union_of(trim);
trim.intersection_of(ssc->snapset.clone_overlap[newest]);
add_interval_usage(trim, ctx->new_stats);
}
- interval_set<uint64_t> keep;
- if (op.extent.offset)
- keep.insert(0, op.extent.offset);
- ssc->snapset.clone_overlap[newest].intersection_of(keep);
}
if (op.extent.offset != oi.size) {
ctx->new_stats.num_bytes -= oi.size;
t.clone_range(coll, osd_op.soid, obs.oi.soid,
op.clonerange.src_offset, op.clonerange.length, op.clonerange.offset);
- write_update_size_and_usage(ctx->new_stats, oi, ssc->snapset,
+ write_update_size_and_usage(ctx->new_stats, oi, ssc->snapset, ctx->modified_ranges,
op.clonerange.offset, op.clonerange.length, false);
}
break;
snapid_t newest = *snapset.clones.rbegin();
add_interval_usage(snapset.clone_overlap[newest], ctx->new_stats);
- // Replace clone_overlap[newest] with an empty interval set since there
- // should no longer be any overlap
- snapset.clone_overlap.erase(newest); // ok, redundant.
- snapset.clone_overlap[newest];
+ if (oi.size > 0) {
+ interval_set<uint64_t> ch;
+ ch.insert(0, oi.size);
+ ctx->modified_ranges.union_of(ch);
+ }
}
if (obs.exists) {
ctx->new_stats.num_objects--;
iter != snapset.clone_overlap.end();
++iter)
overlaps.intersection_of(iter->second);
- snapset.clone_overlap[*snapset.clones.rbegin()] = overlaps;
+
+ if (ctx->obs->oi.size > 0) {
+ interval_set<uint64_t> modified;
+ modified.insert(0, ctx->obs->oi.size);
+ overlaps.intersection_of(modified);
+ modified.subtract(overlaps);
+ ctx->modified_ranges.union_of(modified);
+ }
}
put_object_context(rollback_to);
}
ctx->at_version.version++;
}
+
+ // update most recent clone_overlap
+ if (ctx->new_snapset.clones.size() > 0) {
+ interval_set<uint64_t> &newest_overlap = ctx->new_snapset.clone_overlap.rbegin()->second;
+ ctx->modified_ranges.intersection_of(newest_overlap);
+ newest_overlap.subtract(ctx->modified_ranges);
+ }
// prepend transaction to op_t
t.append(ctx->op_t);
}
-void ReplicatedPG::write_update_size_and_usage(pg_stat_t& stats, object_info_t& oi, SnapSet& ss,
+void ReplicatedPG::write_update_size_and_usage(pg_stat_t& stats, object_info_t& oi,
+ SnapSet& ss, interval_set<uint64_t>& modified,
uint64_t offset, uint64_t length, bool count_bytes)
{
if (ss.clones.size()) {
interval_set<uint64_t> ch;
if (length)
ch.insert(offset, length);
- ch.intersection_of(ss.clone_overlap[newest]);
- ss.clone_overlap[newest].subtract(ch);
+ modified.union_of(ch);
add_interval_usage(ch, stats);
}
if (length && (offset + length > oi.size)) {