mirror of
https://github.com/ceph/ceph
synced 2024-12-28 22:43:29 +00:00
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 <myoungwon.oh@samsung.com>
This commit is contained in:
parent
ac826d1665
commit
4fd423ff04
@ -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<ManifestOp>());
|
||||
ManifestOpRef mop(std::make_shared<ManifestOp>(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<OSDOp>& ops)
|
||||
// start
|
||||
ctx->op_finishers[ctx->current_osd_subop_num].reset(
|
||||
new SetManifestFinisher(osd_op));
|
||||
ManifestOpRef mop = std::make_shared<ManifestOp>(new RefCountCallback(ctx, osd_op));
|
||||
ManifestOpRef mop = std::make_shared<ManifestOp>(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<ManifestOp>());
|
||||
ManifestOpRef mop(std::make_shared<ManifestOp>(obc, nullptr));
|
||||
|
||||
// cdc
|
||||
std::map<uint64_t, bufferlist> 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);
|
||||
|
@ -281,11 +281,12 @@ public:
|
||||
std::map<hobject_t, std::pair<uint64_t, uint64_t>> 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<ManifestOp> ManifestOpRef;
|
||||
std::map<hobject_t, ManifestOpRef> manifest_ops;
|
||||
|
Loading…
Reference in New Issue
Block a user