]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/ReplicatedPG: update all find_object_context() users to handle whiteouts
authorSage Weil <sage@inktank.com>
Tue, 1 Oct 2013 19:12:55 +0000 (12:12 -0700)
committerSage Weil <sage@inktank.com>
Tue, 1 Oct 2013 21:17:59 +0000 (14:17 -0700)
In each case, we treat the whiteout as if we got an ENOENT.

We do not change the semantics of bool exists to avoid breaking lots of
potentially fragile code.  We are only interested in changing the
user-visible behavior of the object, not the way it is internally stored
or managed.

This will likely be refined as we grow acutal users for whiteoutes in the
pool caching code.

Signed-off-by: Sage Weil <sage@inktank.com>
src/osd/ReplicatedPG.cc
src/osd/osd_types.h

index 50d10eca86378b8837a57934c50b2eb4800832df..1a529919bc3bf170f6d3cebe5f6ac0367538561a 100644 (file)
@@ -991,7 +991,8 @@ void ReplicatedPG::do_op(OpRequestRef op)
   dout(25) << __func__ << ": object " << obc->obs.oi.soid
           << " has oi of " << obc->obs.oi << dendl;
   
-  if (!op->may_write() && !obc->obs.exists) {
+  if (!op->may_write() && (!obc->obs.exists ||
+                          obc->obs.oi.is_whiteout())) {
     osd->reply_op_error(op, -ENOENT);
     return;
   }
@@ -1048,6 +1049,8 @@ void ReplicatedPG::do_op(OpRequestRef op)
          wait_for_missing_object(wait_oid, op);
        } else if (r) {
          osd->reply_op_error(op, r);
+       } else if (sobc->obs.oi.is_whiteout()) {
+         osd->reply_op_error(op, -ENOENT);
        } else {
          if (sobc->obs.oi.soid.get_key() != obc->obs.oi.soid.get_key() &&
                   sobc->obs.oi.soid.get_key() != obc->obs.oi.soid.oid.name &&
@@ -1102,6 +1105,8 @@ void ReplicatedPG::do_op(OpRequestRef op)
          wait_for_missing_object(wait_oid, op);
        } else if (r) {
          osd->reply_op_error(op, r);
+       } else if (sobc->obs.oi.is_whiteout()) {
+         osd->reply_op_error(op, -ENOENT);
        } else {
          dout(10) << " clone_oid " << clone_oid << " obc " << sobc << dendl;
          src_obc[clone_oid] = sobc;
@@ -3879,11 +3884,11 @@ int ReplicatedPG::_rollback_to(OpContext *ctx, ceph_osd_op& op)
     hobject_t(soid.oid, soid.get_key(), snapid, soid.hash, info.pgid.pool(), soid.get_namespace()),
     &rollback_to, false, &cloneid);
   if (ret) {
-    if (-ENOENT == ret) {
+    if (-ENOENT == ret || rollback_to->obs.oi.is_whiteout()) {
       // there's no snapshot here, or there's no object.
       // if there's no snapshot, we delete the object; otherwise, do nothing.
       dout(20) << "_rollback_to deleting head on " << soid.oid
-              << " because got ENOENT on find_object_context" << dendl;
+              << " because got ENOENT|whiteout on find_object_context" << dendl;
       if (ctx->obc->obs.oi.watchers.size()) {
        // Cannot delete an object with watchers
        ret = -EBUSY;
index fb1fe3617742e0e0bbd8e0a2645a54084dba07cf..97a5b2e71f814696d1499c277868d24641a8cb16 100644 (file)
@@ -2158,7 +2158,7 @@ WRITE_CLASS_ENCODER(object_info_t)
 
 struct ObjectState {
   object_info_t oi;
-  bool exists;
+  bool exists;         ///< the stored object exists (i.e., we will remember the object_info_t)
 
   ObjectState() : exists(false) {}