From: Sage Weil Date: Fri, 7 Apr 2017 17:18:50 +0000 (-0400) Subject: osd/PrimaryLogPG: delete + ignore_cache is a soft hint X-Git-Tag: v12.0.3~28^2~32 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=de6f09f43a5213b16a9bc952e5fa092c991abb40;p=ceph.git osd/PrimaryLogPG: delete + ignore_cache is a soft hint We may still need to create a whiteout because clones still exist. Arguably delete+ignore_cache is not the right way to remove whiteouts and we should have a separate RADOS operation for this. But we don't. Signed-off-by: Sage Weil --- diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 171565b18d07..de0808378a74 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -5022,7 +5022,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) if (result < 0) break; } - result = _delete_oid(ctx, true); + result = _delete_oid(ctx, true, false); if (result >= 0) { // mark that this is a cache eviction to avoid triggering normal // make_writeable() clone or snapdir object creation in finish_ctx() @@ -5615,7 +5615,9 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) case CEPH_OSD_OP_DELETE: ++ctx->num_write; tracepoint(osd, do_osd_op_pre_delete, soid.oid.name.c_str(), soid.snap.val); - result = _delete_oid(ctx, ctx->ignore_cache); + { + result = _delete_oid(ctx, false, ctx->ignore_cache); + } break; case CEPH_OSD_OP_WATCH: @@ -6375,7 +6377,10 @@ int PrimaryLogPG::_verify_no_head_clones(const hobject_t& soid, return 0; } -inline int PrimaryLogPG::_delete_oid(OpContext *ctx, bool no_whiteout) +inline int PrimaryLogPG::_delete_oid( + OpContext *ctx, + bool no_whiteout, // no whiteouts, no matter what. + bool try_no_whiteout) // try not to whiteout { SnapSet& snapset = ctx->new_snapset; ObjectState& obs = ctx->new_obs; @@ -6385,21 +6390,31 @@ inline int PrimaryLogPG::_delete_oid(OpContext *ctx, bool no_whiteout) // cache: cache: set whiteout on delete? bool whiteout = false; - if (pool.info.cache_mode != pg_pool_t::CACHEMODE_NONE && !no_whiteout) { + if (pool.info.cache_mode != pg_pool_t::CACHEMODE_NONE + && !no_whiteout + && !try_no_whiteout) { whiteout = true; } if (get_osdmap()->test_flag(CEPH_OSDMAP_REQUIRE_LUMINOUS)) { // in luminous or later, we can't delete the head if there are // clones. we trust the caller passing no_whiteout has already // verified they don't exist. - if (!no_whiteout && - (!snapset.clones.empty() || - (!ctx->snapc.snaps.empty() && ctx->snapc.snaps[0] > snapset.seq))) { - dout(20) << __func__ << " has or will have clones; will whiteout" << dendl; - whiteout = true; + if (!snapset.clones.empty() || + (!ctx->snapc.snaps.empty() && ctx->snapc.snaps[0] > snapset.seq)) { + if (no_whiteout) { + dout(20) << __func__ << " has or will have clones but no_whiteout=1" + << dendl; + } else { + dout(20) << __func__ << " has or will have clones; will whiteout" + << dendl; + whiteout = true; + } } } - dout(20) << __func__ << " " << soid << " whiteout=" << (int)whiteout << dendl; + dout(20) << __func__ << " " << soid << " whiteout=" << (int)whiteout + << " no_whiteout=" << (int)no_whiteout + << " try_no_whiteout=" << (int)try_no_whiteout + << dendl; if (!obs.exists || (obs.oi.is_whiteout() && whiteout)) return -ENOENT; @@ -6519,7 +6534,7 @@ int PrimaryLogPG::_rollback_to(OpContext *ctx, ceph_osd_op& op) // Cannot delete an object with watchers ret = -EBUSY; } else { - _delete_oid(ctx, false); + _delete_oid(ctx, false, false); ret = 0; } } else if (ret) { @@ -12475,7 +12490,7 @@ bool PrimaryLogPG::agent_maybe_evict(ObjectContextRef& obc, bool after_flush) ctx->at_version = get_next_version(); assert(ctx->new_obs.exists); - int r = _delete_oid(ctx.get(), true); + int r = _delete_oid(ctx.get(), true, false); if (obc->obs.oi.is_omap()) ctx->delta_stats.num_objects_omap--; ctx->delta_stats.num_evict++; diff --git a/src/osd/PrimaryLogPG.h b/src/osd/PrimaryLogPG.h index c5f33a61168b..87fc9d799674 100644 --- a/src/osd/PrimaryLogPG.h +++ b/src/osd/PrimaryLogPG.h @@ -1703,7 +1703,7 @@ private: // return true if we're creating a local object, false for a // whiteout or no change. void maybe_create_new_object(OpContext *ctx, bool ignore_transaction=false); - int _delete_oid(OpContext *ctx, bool no_whiteout); + int _delete_oid(OpContext *ctx, bool no_whiteout, bool try_no_whiteout); int _rollback_to(OpContext *ctx, ceph_osd_op& op); public: bool is_missing_object(const hobject_t& oid) const;