From 74382b040fed44089604dd2da5b6a695da435226 Mon Sep 17 00:00:00 2001 From: Chang Liu Date: Wed, 8 Jan 2020 02:11:44 +0000 Subject: [PATCH] os/kstore: do not cache in-fight stripes on read ops to avoid memory leaks Fixes: http://tracker.ceph.com/issues/39665 Signed-off-by: Chang Liu Signed-off-by: lvshanchun lvshanchun@gmail.com --- src/os/kstore/KStore.cc | 24 ++++++++++++++++-------- src/os/kstore/KStore.h | 3 ++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/os/kstore/KStore.cc b/src/os/kstore/KStore.cc index ce18d967701a8..77ccfe0055263 100644 --- a/src/os/kstore/KStore.cc +++ b/src/os/kstore/KStore.cc @@ -1233,7 +1233,7 @@ int KStore::read( if (offset == length && offset == 0) length = o->onode.size; - r = _do_read(o, offset, length, bl, op_flags); + r = _do_read(o, offset, length, bl, false, op_flags); out: dout(10) << __func__ << " " << ch->cid << " " << oid @@ -1247,6 +1247,7 @@ int KStore::_do_read( uint64_t offset, size_t length, bufferlist& bl, + bool do_cache, uint32_t op_flags) { int r = 0; @@ -1274,7 +1275,7 @@ int KStore::_do_read( stripe_off = offset % stripe_size; while (length > 0) { bufferlist stripe; - _do_read_stripe(o, offset - stripe_off, &stripe); + _do_read_stripe(o, offset - stripe_off, &stripe, do_cache); dout(30) << __func__ << " stripe " << offset - stripe_off << " got " << stripe.length() << dendl; unsigned swant = std::min(stripe_size - stripe_off, length); @@ -2593,8 +2594,15 @@ void KStore::_dump_onode(OnodeRef o) } } -void KStore::_do_read_stripe(OnodeRef o, uint64_t offset, bufferlist *pbl) +void KStore::_do_read_stripe(OnodeRef o, uint64_t offset, bufferlist *pbl, bool do_cache) { + if (!do_cache) { + string key; + get_data_key(o->onode.nid, offset, &key); + db->get(PREFIX_DATA, key, pbl); + return; + } + map::iterator p = o->pending_stripes.find(offset); if (p == o->pending_stripes.end()) { string key; @@ -2664,7 +2672,7 @@ int KStore::_do_write(TransContext *txc, } uint64_t stripe_off = offset - offset_rem; bufferlist prev; - _do_read_stripe(o, stripe_off, &prev); + _do_read_stripe(o, stripe_off, &prev, true); dout(20) << __func__ << " read previous stripe " << stripe_off << ", got " << prev.length() << dendl; bufferlist bl; @@ -2755,7 +2763,7 @@ int KStore::_zero(TransContext *txc, while (pos < offset + length) { if (stripe_off || end - pos < stripe_size) { bufferlist stripe; - _do_read_stripe(o, pos - stripe_off, &stripe); + _do_read_stripe(o, pos - stripe_off, &stripe, true); dout(30) << __func__ << " stripe " << pos - stripe_off << " got " << stripe.length() << dendl; bufferlist bl; @@ -2812,7 +2820,7 @@ int KStore::_do_truncate(TransContext *txc, OnodeRef o, uint64_t offset) while (pos < o->onode.size) { if (stripe_off) { bufferlist stripe; - _do_read_stripe(o, pos - stripe_off, &stripe); + _do_read_stripe(o, pos - stripe_off, &stripe, true); dout(30) << __func__ << " stripe " << pos - stripe_off << " got " << stripe.length() << dendl; bufferlist t; @@ -3149,7 +3157,7 @@ int KStore::_clone(TransContext *txc, // data oldo->flush(); - r = _do_read(oldo, 0, oldo->onode.size, bl, 0); + r = _do_read(oldo, 0, oldo->onode.size, bl, true, 0); if (r < 0) goto out; @@ -3219,7 +3227,7 @@ int KStore::_clone_range(TransContext *txc, newo->exists = true; _assign_nid(txc, newo); - r = _do_read(oldo, srcoff, length, bl, 0); + r = _do_read(oldo, srcoff, length, bl, true, 0); if (r < 0) goto out; diff --git a/src/os/kstore/KStore.h b/src/os/kstore/KStore.h index 06d2d61f20030..428dd4aab361c 100644 --- a/src/os/kstore/KStore.h +++ b/src/os/kstore/KStore.h @@ -392,7 +392,7 @@ private: kv_stop = false; } - void _do_read_stripe(OnodeRef o, uint64_t offset, bufferlist *pbl); + void _do_read_stripe(OnodeRef o, uint64_t offset, bufferlist *pbl, bool do_cache); void _do_write_stripe(TransContext *txc, OnodeRef o, uint64_t offset, bufferlist& bl); void _do_remove_stripe(TransContext *txc, OnodeRef o, uint64_t offset); @@ -478,6 +478,7 @@ public: uint64_t offset, size_t len, bufferlist& bl, + bool do_cache, uint32_t op_flags = 0); using ObjectStore::fiemap; -- 2.39.5