From: Sage Weil Date: Tue, 1 Oct 2013 19:12:55 +0000 (-0700) Subject: osd/ReplicatedPG: update all find_object_context() users to handle whiteouts X-Git-Tag: v0.71~48^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1aa606711e8ba84e7013193c80d757a60a902d50;p=ceph.git osd/ReplicatedPG: update all find_object_context() users to handle whiteouts 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 --- diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 50d10eca8637..1a529919bc3b 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -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; diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index fb1fe3617742..97a5b2e71f81 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -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) {}