diff options
author | Sage Weil <sage@inktank.com> | 2013-10-01 12:12:55 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-10-01 12:12:55 -0700 |
commit | 13b8948e051163c60f3291368ea09d278dd30585 (patch) | |
tree | aa9e4d97da9cd15696471bb49774f3cbfcb33e3f | |
parent | db479b525bff75b6e0fe908601b5a963e1ded30f (diff) | |
download | ceph-13b8948e051163c60f3291368ea09d278dd30585.tar.gz |
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 <sage@inktank.com>
-rw-r--r-- | src/osd/ReplicatedPG.cc | 11 | ||||
-rw-r--r-- | src/osd/osd_types.h | 2 |
2 files changed, 9 insertions, 4 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 50d10eca863..8adec157e7e 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 aebfd113838..903222749a2 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) {} |