summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-10-01 12:12:55 -0700
committerSage Weil <sage@inktank.com>2013-10-01 12:12:55 -0700
commit13b8948e051163c60f3291368ea09d278dd30585 (patch)
treeaa9e4d97da9cd15696471bb49774f3cbfcb33e3f
parentdb479b525bff75b6e0fe908601b5a963e1ded30f (diff)
downloadceph-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.cc11
-rw-r--r--src/osd/osd_types.h2
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) {}