]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/osd: whiteout removed head object with existing clones
authorMatan Breizman <mbreizma@redhat.com>
Wed, 3 Aug 2022 11:26:27 +0000 (11:26 +0000)
committerMatan Breizman <mbreizma@redhat.com>
Thu, 18 Aug 2022 10:59:26 +0000 (10:59 +0000)
Signed-off-by: Matan Breizman <mbreizma@redhat.com>
src/crimson/os/cyanstore/cyan_store.cc
src/crimson/osd/ops_executer.cc
src/crimson/osd/pg.cc
src/crimson/osd/pg_backend.cc
src/crimson/osd/pg_backend.h

index 03244150743a5395d4326805afe97aa511b348cd..0126ce02f1298c490a53955aca60f49cc3b2b52e 100644 (file)
@@ -357,6 +357,7 @@ seastar::future<> CyanStore::do_transaction(CollectionRef ch,
       }
       break;
       case Transaction::OP_TOUCH:
+      case Transaction::OP_CREATE:
       {
         coll_t cid = i.get_cid(op->cid);
         ghobject_t oid = i.get_oid(op->oid);
index 7a9064de99d981275b20ffc37385c12009c9fe75..74fffa84122f425c10a69646750255037e306ee2 100644 (file)
@@ -578,9 +578,19 @@ OpsExecuter::do_execute_op(OSDOp& osd_op)
       return backend.setxattr(os, osd_op, txn, delta_stats);
     });
   case CEPH_OSD_OP_DELETE:
-    return do_write_op([this](auto& backend, auto& os, auto& txn) {
-      return backend.remove(os, txn, delta_stats);
+  {
+    bool whiteout = false;
+    if (!obc->ssc->snapset.clones.empty() ||
+        (snapc.snaps.size() &&                      // there are snaps
+        snapc.snaps[0] > obc->ssc->snapset.seq)) {  // existing obj is old
+      logger().debug("{} has or will have clones, will whiteout {}",
+                     __func__, obc->obs.oi.soid);
+      whiteout = true;
+    }
+    return do_write_op([this, whiteout](auto& backend, auto& os, auto& txn) {
+      return backend.remove(os, txn, delta_stats, whiteout);
     });
+  }
   case CEPH_OSD_OP_CALL:
     return this->do_op_call(osd_op);
   case CEPH_OSD_OP_STAT:
@@ -815,6 +825,10 @@ const object_info_t OpsExecuter::prepare_clone(
   static_snap_oi.version = osd_op_params->at_version;
   static_snap_oi.prior_version = obc->obs.oi.version;
   static_snap_oi.copy_user_bits(obc->obs.oi);
+  if (static_snap_oi.is_whiteout()) {
+    // clone shouldn't be marked as whiteout
+    static_snap_oi.clear_flag(object_info_t::FLAG_WHITEOUT);
+  }
 
   if (pg->is_primary()) {
     // lookup_or_create
index c6c3f42b9eb3d9e207098ee2b44d3e02fbe63e3f..30fc937cbba5f1edd6d5f656af1fb64fac5c296f 100644 (file)
@@ -1053,6 +1053,10 @@ PG::with_clone_obc(hobject_t oid, with_obc_func_t&& func)
   assert(!oid.is_head());
   return with_head_obc<RWState::RWREAD>(oid.get_head(),
     [oid, func=std::move(func), this](auto head) -> load_obc_iertr::future<> {
+    if (!head->obs.exists) {
+      logger().error("with_clone_obc: {} head doesn't exist", head->obs.oi.soid);
+      return load_obc_iertr::future<>{crimson::ct_error::object_corrupted::make()};
+    }
     auto coid = resolve_oid(head->get_ro_ss(), oid);
     if (!coid) {
       logger().error("with_clone_obc: {} clone not found", coid);
@@ -1067,6 +1071,7 @@ PG::with_clone_obc(hobject_t oid, with_obc_func_t&& func)
         logger().debug("with_clone_obc: found {} in cache", clone->get_oid());
       } else {
         logger().debug("with_clone_obc: cache miss on {}", clone->get_oid());
+        //TODO: generalize load_head_obc -> load_obc (support head/clone obc)
         loaded = clone->template with_promoted_lock<State, IOInterruptCondition>(
           [clone, head, this] {
           return backend->load_metadata(clone->get_oid()).safe_then_interruptible(
index 77dcc580191987c10cdec398b0f0286294387b33..bdadabb8e19315a11d72771fbe393bc5fbdcbd4e 100644 (file)
@@ -827,7 +827,8 @@ PGBackend::create_iertr::future<> PGBackend::create(
     }
   }
   maybe_create_new_object(os, txn, delta_stats);
-  txn.nop();
+  txn.create(coll->get_cid(),
+             ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
   return seastar::now();
 }
 
@@ -849,24 +850,38 @@ PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn)
 
 PGBackend::remove_iertr::future<>
 PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn,
-  object_stat_sum_t& delta_stats)
+  object_stat_sum_t& delta_stats, bool whiteout)
 {
   if (!os.exists) {
     return crimson::ct_error::enoent::make();
   }
-  // todo: snapset
+
+  if (whiteout && os.oi.is_whiteout()) {
+    logger().debug("{} whiteout set on {} ",__func__, os.oi.soid);
+    return seastar::now();
+  }
   txn.remove(coll->get_cid(),
             ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
   delta_stats.num_bytes -= os.oi.size;
   os.oi.size = 0;
   os.oi.new_object();
-  os.exists = false;
+
+  // todo: clone_overlap
+  if (whiteout) {
+    logger().debug("{} setting whiteout on {} ",__func__, os.oi.soid);
+    os.oi.set_flag(object_info_t::FLAG_WHITEOUT);
+    delta_stats.num_whiteouts++;
+    txn.create(coll->get_cid(),
+               ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard});
+    return seastar::now();
+  }
   // todo: update watchers
   if (os.oi.is_whiteout()) {
     os.oi.clear_flag(object_info_t::FLAG_WHITEOUT);
     delta_stats.num_whiteouts--;
   }
   delta_stats.num_objects--;
+  os.exists = false;
   return seastar::now();
 }
 
index 34ea12652afe3fd304fa950e04ce51d2bd90672a..7777b53781c9559692f3d8cbf0699f40a9251c40 100644 (file)
@@ -147,7 +147,8 @@ public:
   remove_iertr::future<> remove(
     ObjectState& os,
     ceph::os::Transaction& txn,
-    object_stat_sum_t& delta_stats);
+    object_stat_sum_t& delta_stats,
+    bool whiteout);
   interruptible_future<> remove(
     ObjectState& os,
     ceph::os::Transaction& txn);