@@ -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
583587void 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
9761014PGBackend::remove_iertr::future<>
9771015PGBackend::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}
0 commit comments