diff options
author | Sage Weil <sage@inktank.com> | 2013-10-22 18:06:41 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-10-22 18:07:35 -0700 |
commit | cd3a35aac7b2fbc5080c780e855ab1afcdf98cdb (patch) | |
tree | 9e9f9882d1bd41101766a43fabd949169a90c0f5 | |
parent | 0e63847bba82e40cd14da9f36b318bb28de55f0e (diff) | |
download | ceph-cd3a35aac7b2fbc5080c780e855ab1afcdf98cdb.tar.gz |
osd/ReplicatedPG: handle is_whiteout in do_osd_ops()
Most of the time we handle whiteouts by returning ENOENT before we even
get this far. However, for a mixed read/write transaction (e.g., a guard)
or certain ops (like create exclusive) we need to deal with the
exists == true and whiteout flag set case explicitly.
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/osd/ReplicatedPG.cc | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 849a68ac41c..94a8e0ab62b 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -2713,7 +2713,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) case CEPH_OSD_OP_STAT: // note: stat does not require RD { - if (obs.exists) { + if (obs.exists && !oi.is_whiteout()) { ::encode(oi.size, osd_op.outdata); ::encode(oi.mtime, osd_op.outdata); dout(10) << "stat oi has " << oi.size << " " << oi.mtime << dendl; @@ -3059,7 +3059,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) } if (op.extent.truncate_seq > seq) { // write arrives before trimtrunc - if (obs.exists) { + if (obs.exists && !oi.is_whiteout()) { dout(10) << " truncate_seq " << op.extent.truncate_seq << " > current " << seq << ", truncating to " << op.extent.truncate_size << dendl; t.truncate(coll, soid, op.extent.truncate_size); @@ -3133,7 +3133,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) if (result < 0) break; assert(op.extent.length); - if (obs.exists) { + if (obs.exists && !oi.is_whiteout()) { t.zero(coll, soid, op.extent.offset, op.extent.length); interval_set<uint64_t> ch; ch.insert(op.extent.offset, op.extent.length); @@ -3148,7 +3148,8 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) ++ctx->num_write; { int flags = le32_to_cpu(op.flags); - if (obs.exists && (flags & CEPH_OSD_OP_FLAG_EXCL)) { + if (obs.exists && !oi.is_whiteout() && + (flags & CEPH_OSD_OP_FLAG_EXCL)) { result = -EEXIST; /* this is an exclusive create */ } else { if (osd_op.indata.length()) { @@ -3162,7 +3163,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) goto fail; } if (category.size()) { - if (obs.exists) { + if (obs.exists && !oi.is_whiteout()) { if (obs.oi.category != category) result = -EEXIST; // category cannot be reset } else { @@ -3187,7 +3188,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) ++ctx->num_write; { // truncate - if (!obs.exists) { + if (!obs.exists || oi.is_whiteout()) { dout(10) << " object dne, truncate is a no-op" << dendl; break; } @@ -3543,7 +3544,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) case CEPH_OSD_OP_OMAP_CMP: ++ctx->num_read; { - if (!obs.exists) { + if (!obs.exists || oi.is_whiteout()) { result = -ENOENT; break; } @@ -3650,7 +3651,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) case CEPH_OSD_OP_OMAPCLEAR: ++ctx->num_write; { - if (!obs.exists) { + if (!obs.exists || oi.is_whiteout()) { result = -ENOENT; break; } @@ -3663,7 +3664,7 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& ops) case CEPH_OSD_OP_OMAPRMKEYS: ++ctx->num_write; { - if (!obs.exists) { + if (!obs.exists || oi.is_whiteout()) { result = -ENOENT; break; } |