Skip to content

Commit b5df21f

Browse files
committed
crimson/osd: Keep track of modified_ranges
* `modifies_ranges` interval_set is added to osd_op_params_t * keep track of modified_ranges while executing relevant ops * Add `osd_op_params` parameter to `PGBackend::remove()`. Signed-off-by: Matan Breizman <[email protected]>
1 parent 1367490 commit b5df21f

File tree

4 files changed

+108
-28
lines changed

4 files changed

+108
-28
lines changed

src/crimson/osd/ops_executer.cc

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,16 @@ OpsExecuter::do_execute_op(OSDOp& osd_op)
674674
whiteout = true;
675675
}
676676
return do_write_op([this, whiteout](auto& backend, auto& os, auto& txn) {
677-
return backend.remove(os, txn, delta_stats, whiteout);
677+
int num_bytes = 0;
678+
// Calculate num_bytes to be removed
679+
if (obc->obs.oi.soid.is_snap()) {
680+
ceph_assert(obc->ssc->snapset.clone_overlap.count(obc->obs.oi.soid.snap));
681+
num_bytes = obc->ssc->snapset.get_clone_bytes(obc->obs.oi.soid.snap);
682+
} else {
683+
num_bytes = obc->obs.oi.size;
684+
}
685+
return backend.remove(os, txn, *osd_op_params,
686+
delta_stats, whiteout, num_bytes);
678687
});
679688
}
680689
case CEPH_OSD_OP_CALL:
@@ -961,7 +970,17 @@ std::unique_ptr<OpsExecuter::CloningContext> OpsExecuter::execute_clone(
961970
osd_op_params->at_version.version++;
962971
encode(cloned_snaps, cloning_ctx->log_entry.snaps);
963972

964-
// TODO: update most recent clone_overlap and usage stats
973+
// update most recent clone_overlap and usage stats
974+
assert(cloning_ctx->new_snapset.clones.size() > 0);
975+
// In classic, we check for evicted clones before
976+
// adjusting the clone_overlap.
977+
// This check is redundant here since `clone_obc`
978+
// was just created (See prepare_clone()).
979+
interval_set<uint64_t> &newest_overlap =
980+
cloning_ctx->new_snapset.clone_overlap.rbegin()->second;
981+
osd_op_params->modified_ranges.intersection_of(newest_overlap);
982+
delta_stats.num_bytes += osd_op_params->modified_ranges.size();
983+
newest_overlap.subtract(osd_op_params->modified_ranges);
965984
return cloning_ctx;
966985
}
967986

src/crimson/osd/osd_operations/osdop_params.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ struct osd_op_params_t {
1717
version_t user_at_version = 0;
1818
bool user_modify = false;
1919
ObjectCleanRegions clean_regions;
20-
20+
interval_set<uint64_t> modified_ranges;
21+
//TODO: Move delta_stats to osd_op_params_t
2122
osd_op_params_t() = default;
2223
};

src/crimson/osd/pg_backend.cc

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,9 @@ PGBackend::write_iertr::future<> PGBackend::_writefull(
506506
coll->get_cid(), ghobject_t{os.oi.soid}, 0, bl.length(),
507507
bl, flags);
508508
update_size_and_usage(
509-
delta_stats, os.oi, 0,
509+
delta_stats,
510+
osd_op_params.modified_ranges,
511+
os.oi, 0,
510512
bl.length(), true);
511513
osd_op_params.clean_regions.mark_data_region_dirty(
512514
0,
@@ -543,7 +545,9 @@ PGBackend::write_iertr::future<> PGBackend::_truncate(
543545
coll->get_cid(),
544546
ghobject_t{os.oi.soid}, offset);
545547
if (os.oi.size > offset) {
546-
// TODO: modified_ranges.union_of(trim);
548+
interval_set<uint64_t> trim;
549+
trim.insert(offset, os.oi.size - offset);
550+
osd_op_params.modified_ranges.union_of(trim);
547551
osd_op_params.clean_regions.mark_data_region_dirty(
548552
offset,
549553
os.oi.size - offset);
@@ -581,9 +585,19 @@ bool PGBackend::maybe_create_new_object(
581585
}
582586

583587
void PGBackend::update_size_and_usage(object_stat_sum_t& delta_stats,
588+
interval_set<uint64_t>& modified,
584589
object_info_t& oi, uint64_t offset,
585590
uint64_t length, bool write_full)
586591
{
592+
interval_set<uint64_t> ch;
593+
if (write_full) {
594+
if (oi.size) {
595+
ch.insert(0, oi.size);
596+
} else if (length) {
597+
ch.insert(offset, length);
598+
}
599+
modified.union_of(ch);
600+
}
587601
if (write_full ||
588602
(offset + length > oi.size && length)) {
589603
uint64_t new_size = offset + length;
@@ -681,12 +695,14 @@ PGBackend::write_iertr::future<> PGBackend::write(
681695
ghobject_t{os.oi.soid}, op.extent.truncate_size);
682696
if (op.extent.truncate_size != os.oi.size) {
683697
os.oi.size = length;
684-
if (op.extent.truncate_size > os.oi.size) {
685-
osd_op_params.clean_regions.mark_data_region_dirty(os.oi.size,
686-
op.extent.truncate_size - os.oi.size);
687-
} else {
688-
osd_op_params.clean_regions.mark_data_region_dirty(op.extent.truncate_size,
689-
os.oi.size - op.extent.truncate_size);
698+
if (op.extent.truncate_size < os.oi.size) {
699+
interval_set<uint64_t> trim;
700+
trim.insert(op.extent.truncate_size,
701+
os.oi.size - op.extent.truncate_size);
702+
osd_op_params.modified_ranges.union_of(trim);
703+
osd_op_params.clean_regions.mark_data_region_dirty(
704+
op.extent.truncate_size, os.oi.size - op.extent.truncate_size);
705+
os.oi.clear_data_digest();
690706
}
691707
}
692708
truncate_update_size_and_usage(delta_stats, os.oi, op.extent.truncate_size);
@@ -705,10 +721,12 @@ PGBackend::write_iertr::future<> PGBackend::write(
705721
} else {
706722
txn.write(coll->get_cid(), ghobject_t{os.oi.soid},
707723
offset, length, std::move(buf), op.flags);
708-
update_size_and_usage(delta_stats, os.oi, offset, length);
724+
update_size_and_usage(delta_stats, osd_op_params.modified_ranges,
725+
os.oi, offset, length);
709726
}
710727
osd_op_params.clean_regions.mark_data_region_dirty(op.extent.offset,
711728
op.extent.length);
729+
logger().debug("{} clean_regions modified", __func__);
712730

713731
return seastar::now();
714732
}
@@ -738,7 +756,8 @@ PGBackend::interruptible_future<> PGBackend::write_same(
738756
txn.write(coll->get_cid(), ghobject_t{os.oi.soid},
739757
op.writesame.offset, len,
740758
std::move(repeated_indata), op.flags);
741-
update_size_and_usage(delta_stats, os.oi, op.writesame.offset, len);
759+
update_size_and_usage(delta_stats, osd_op_params.modified_ranges,
760+
os.oi, op.writesame.offset, len);
742761
osd_op_params.clean_regions.mark_data_region_dirty(op.writesame.offset, len);
743762
return seastar::now();
744763
}
@@ -788,7 +807,7 @@ PGBackend::rollback_iertr::future<> PGBackend::rollback(
788807
target_coid.snap = snapid;
789808
return obc_loader.with_clone_obc_only<RWState::RWWRITE>(
790809
head, target_coid,
791-
[this, &os, &txn, &delta_stats, &osd_op_params]
810+
[this, &os, &txn, &delta_stats, &osd_op_params, &snapid]
792811
(auto, auto resolved_obc) {
793812
if (resolved_obc->obs.oi.soid.is_head()) {
794813
// no-op: The resolved oid returned the head object
@@ -824,9 +843,24 @@ PGBackend::rollback_iertr::future<> PGBackend::rollback(
824843
osd_op_params.clean_regions.mark_data_region_dirty(0,
825844
std::max(os.oi.size, resolved_obc->obs.oi.size));
826845
osd_op_params.clean_regions.mark_omap_dirty();
827-
// TODO: 3) Calculate clone_overlaps by following overlaps
828-
// forward from rollback snapshot
829-
// https://tracker.ceph.com/issues/58263
846+
847+
// 3) Calculate clone_overlaps by following overlaps
848+
const auto& clone_overlap =
849+
resolved_obc->ssc->snapset.clone_overlap;
850+
auto iter = clone_overlap.lower_bound(snapid);
851+
ceph_assert(iter != clone_overlap.end());
852+
interval_set<uint64_t> overlaps = iter->second;
853+
for (const auto&i: clone_overlap) {
854+
overlaps.intersection_of(i.second);
855+
}
856+
857+
if (os.oi.size > 0) {
858+
interval_set<uint64_t> modified;
859+
modified.insert(0, os.oi.size);
860+
overlaps.intersection_of(modified);
861+
modified.subtract(overlaps);
862+
osd_op_params.modified_ranges.union_of(modified);
863+
}
830864
return rollback_iertr::now();
831865
}).safe_then_interruptible([] {
832866
logger().debug("PGBackend::rollback succefully");
@@ -835,12 +869,13 @@ PGBackend::rollback_iertr::future<> PGBackend::rollback(
835869
// if there's no snapshot, we delete the object;
836870
// otherwise, do nothing.
837871
crimson::ct_error::enoent::handle(
838-
[this, &os, &snapid, &txn, &delta_stats, &snapc, &ss] {
872+
[this, &os, &snapid, &txn, &delta_stats, &snapc, &ss, &osd_op_params] {
839873
logger().debug("PGBackend::rollback: deleting head on {}"
840874
" with snap_id of {}"
841875
" because got ENOENT|whiteout on obc lookup",
842876
os.oi.soid, snapid);
843-
return remove(os, txn, delta_stats, should_whiteout(ss, snapc));
877+
return remove(os, txn, osd_op_params, delta_stats,
878+
should_whiteout(ss, snapc), os.oi.size);
844879
}),
845880
rollback_ertr::pass_further{},
846881
crimson::ct_error::assert_all{"unexpected error in rollback"}
@@ -863,8 +898,9 @@ PGBackend::append_ierrorator::future<> PGBackend::append(
863898
txn.write(coll->get_cid(), ghobject_t{os.oi.soid},
864899
os.oi.size /* offset */, op.extent.length,
865900
std::move(osd_op.indata), op.flags);
866-
update_size_and_usage(delta_stats, os.oi, os.oi.size,
867-
op.extent.length);
901+
update_size_and_usage(delta_stats,
902+
osd_op_params.modified_ranges,
903+
os.oi, os.oi.size, op.extent.length);
868904
osd_op_params.clean_regions.mark_data_region_dirty(os.oi.size,
869905
op.extent.length);
870906
}
@@ -921,7 +957,9 @@ PGBackend::write_iertr::future<> PGBackend::zero(
921957
ghobject_t{os.oi.soid},
922958
op.extent.offset,
923959
op.extent.length);
924-
// TODO: modified_ranges.union_of(zeroed);
960+
interval_set<uint64_t> ch;
961+
ch.insert(op.extent.offset, op.extent.length);
962+
osd_op_params.modified_ranges.union_of(ch);
925963
osd_op_params.clean_regions.mark_data_region_dirty(op.extent.offset,
926964
op.extent.length);
927965
delta_stats.num_wr++;
@@ -975,7 +1013,10 @@ PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn)
9751013

9761014
PGBackend::remove_iertr::future<>
9771015
PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn,
978-
object_stat_sum_t& delta_stats, bool whiteout)
1016+
osd_op_params_t& osd_op_params,
1017+
object_stat_sum_t& delta_stats,
1018+
bool whiteout,
1019+
int num_bytes)
9791020
{
9801021
if (!os.exists) {
9811022
return crimson::ct_error::enoent::make();
@@ -991,17 +1032,28 @@ PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn,
9911032
}
9921033
txn.remove(coll->get_cid(),
9931034
ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
994-
delta_stats.num_bytes -= os.oi.size;
9951035

9961036
if (os.oi.is_omap()) {
9971037
os.oi.clear_flag(object_info_t::FLAG_OMAP);
9981038
delta_stats.num_objects_omap--;
9991039
}
10001040

1041+
if (os.oi.size > 0) {
1042+
interval_set<uint64_t> ch;
1043+
ch.insert(0, os.oi.size);
1044+
osd_op_params.modified_ranges.union_of(ch);
1045+
osd_op_params.clean_regions.mark_data_region_dirty(0, os.oi.size);
1046+
}
1047+
1048+
osd_op_params.clean_regions.mark_omap_dirty();
1049+
delta_stats.num_wr++;
1050+
// num_bytes of the removed clone or head object
1051+
delta_stats.num_bytes -= num_bytes;
10011052
os.oi.size = 0;
10021053
os.oi.new_object();
10031054

1004-
// todo: clone_overlap
1055+
// todo: update watchers
1056+
10051057
if (whiteout) {
10061058
logger().debug("{} setting whiteout on {} ",__func__, os.oi.soid);
10071059
os.oi.set_flag(object_info_t::FLAG_WHITEOUT);
@@ -1010,12 +1062,17 @@ PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn,
10101062
ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
10111063
return seastar::now();
10121064
}
1013-
// todo: update watchers
1065+
1066+
// delete the head
1067+
delta_stats.num_objects--;
1068+
if (os.oi.soid.is_snap()) {
1069+
delta_stats.num_object_clones--;
1070+
}
10141071
if (os.oi.is_whiteout()) {
1072+
logger().debug("{} deleting whiteout on {}", __func__, os.oi.soid);
10151073
os.oi.clear_flag(object_info_t::FLAG_WHITEOUT);
10161074
delta_stats.num_whiteouts--;
10171075
}
1018-
delta_stats.num_objects--;
10191076
os.exists = false;
10201077
return seastar::now();
10211078
}

src/crimson/osd/pg_backend.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,10 @@ class PGBackend
149149
remove_iertr::future<> remove(
150150
ObjectState& os,
151151
ceph::os::Transaction& txn,
152+
osd_op_params_t& osd_op_params,
152153
object_stat_sum_t& delta_stats,
153-
bool whiteout);
154+
bool whiteout,
155+
int num_bytes);
154156
interruptible_future<> remove(
155157
ObjectState& os,
156158
ceph::os::Transaction& txn);
@@ -432,6 +434,7 @@ class PGBackend
432434
ceph::os::Transaction& txn,
433435
object_stat_sum_t& delta_stats);
434436
void update_size_and_usage(object_stat_sum_t& delta_stats,
437+
interval_set<uint64_t>& modified,
435438
object_info_t& oi, uint64_t offset,
436439
uint64_t length, bool write_full = false);
437440
void truncate_update_size_and_usage(

0 commit comments

Comments
 (0)