From: myoungwon oh Date: Mon, 3 Jan 2022 11:13:33 +0000 (+0900) Subject: osd: fix ObjectContextRef reference leak X-Git-Tag: v18.0.0~1307^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4fd423ff04412f7160ccdf4565ef77e709a87518;p=ceph.git osd: fix ObjectContextRef reference leak After start_dedup() is called on the object, several CREATE_OR_GET_REFs are sent. In the meantime, the ObjectContextRef can be evicted from the cache while the deduplication is in progress. To avoid this situation, this commit adds ObjectContextRef to ManifestOp as FlushOp works. Signed-off-by: Myoungwon Oh --- diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 3023b6376f19..9e4cf1b449e0 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -3590,7 +3590,7 @@ bool PrimaryLogPG::inc_refcount_by_set(OpContext* ctx, object_manifest_t& set_ch refs); bool need_inc_ref = false; if (!refs.is_empty()) { - ManifestOpRef mop(std::make_shared()); + ManifestOpRef mop(std::make_shared(ctx->obc, nullptr)); for (auto c : set_chunk.chunk_map) { auto p = refs.find(c.second.oid); if (p == refs.end()) { @@ -7113,7 +7113,7 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) // start ctx->op_finishers[ctx->current_osd_subop_num].reset( new SetManifestFinisher(osd_op)); - ManifestOpRef mop = std::make_shared(new RefCountCallback(ctx, osd_op)); + ManifestOpRef mop = std::make_shared(ctx->obc, new RefCountCallback(ctx, osd_op)); auto* fin = new C_SetManifestRefCountDone(this, soid, 0); ceph_tid_t tid = refcount_manifest(soid, target, refcount_t::INCREMENT_REF, fin, std::nullopt); @@ -10463,7 +10463,7 @@ int PrimaryLogPG::start_dedup(OpRequestRef op, ObjectContextRef obc) * The operations to make dedup chunks are tracked by a ManifestOp. * This op will be finished if all the operations are completed. */ - ManifestOpRef mop(std::make_shared()); + ManifestOpRef mop(std::make_shared(obc, nullptr)); // cdc std::map chunks; @@ -10619,12 +10619,8 @@ int PrimaryLogPG::finish_set_dedup(hobject_t oid, int r, ceph_tid_t tid, uint64_ // there are on-going works return -EINPROGRESS; } - ObjectContextRef obc = get_object_context(oid, false); - if (!obc) { - if (mop->op) - osd->reply_op_error(mop->op, -EINVAL); - return -EINVAL; - } + ObjectContextRef obc = mop->obc; + ceph_assert(obc); ceph_assert(obc->is_blocked()); obc->stop_block(); kick_object_context_blocked(obc); diff --git a/src/osd/PrimaryLogPG.h b/src/osd/PrimaryLogPG.h index b92c46bf4a92..2605c992bca3 100644 --- a/src/osd/PrimaryLogPG.h +++ b/src/osd/PrimaryLogPG.h @@ -281,11 +281,12 @@ public: std::map> chunks; uint64_t num_chunks = 0; object_manifest_t new_manifest; + ObjectContextRef obc; - ManifestOp(RefCountCallback* cb) - : cb(cb) {} - ManifestOp() = default; + ManifestOp(ObjectContextRef obc, RefCountCallback* cb) + : cb(cb), obc(obc) {} + ManifestOp() = delete; }; typedef std::shared_ptr ManifestOpRef; std::map manifest_ops;