diff --git a/src/common/cohort_lru.h b/src/common/cohort_lru.h index 3c789582f5817..2383fc95d7a3b 100644 --- a/src/common/cohort_lru.h +++ b/src/common/cohort_lru.h @@ -42,6 +42,8 @@ namespace cohort { typedef bi::link_mode link_mode; + class ObjectFactory; // Forward declaration + class Object { private: @@ -70,7 +72,7 @@ namespace cohort { uint32_t get_refcnt() const { return lru_refcnt; } - virtual bool reclaim() = 0; + virtual bool reclaim(const ObjectFactory* newobj_fac) = 0; virtual ~Object() {} @@ -132,7 +134,7 @@ namespace cohort { (!(o->lru_flags & FLAG_EVICTING))); } - Object* evict_block() { + Object* evict_block(const ObjectFactory* newobj_fac) { uint32_t lane_ix = next_evict_lane(); for (int ix = 0; ix < n_lanes; ++ix, lane_ix = next_evict_lane()) { @@ -144,7 +146,7 @@ namespace cohort { ++(o->lru_refcnt); o->lru_flags |= FLAG_EVICTING; lane.lock.unlock(); - if (o->reclaim()) { + if (o->reclaim(newobj_fac)) { lane.lock.lock(); --(o->lru_refcnt); /* assertions that o state has not changed across @@ -236,7 +238,7 @@ namespace cohort { Object* insert(ObjectFactory* fac, Edge edge, uint32_t& flags) { /* use supplied functor to re-use an evicted object, or * allocate a new one of the descendant type */ - Object* o = evict_block(); + Object* o = evict_block(fac); if (o) { fac->recycle(o); /* recycle existing object */ flags |= FLAG_RECYCLE; @@ -425,7 +427,9 @@ namespace cohort { lat.lock->unlock(); return v; } /* find_latch */ - + bool is_same_partition(uint64_t lhs, uint64_t rhs) { + return ((lhs % n_part) == (rhs % n_part)); + } void insert_latched(T* v, Latch& lat, uint32_t flags) { (void) lat.p->tr.insert_unique_commit(*v, lat.commit_data); if (flags & FLAG_UNLOCK) diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 442096d1e2dde..07ff14da79b3b 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -1207,10 +1207,19 @@ namespace rgw { return dar; } /* RGWFileHandle::decode_attrs */ - bool RGWFileHandle::reclaim() { + bool RGWFileHandle::reclaim(const cohort::lru::ObjectFactory* newobj_fac) { lsubdout(fs->get_context(), rgw, 17) << __func__ << " " << *this << dendl; + auto factory = dynamic_cast(newobj_fac); + if (factory == nullptr) { + return false; + } + /* make sure the reclaiming object is the same partiton with newobject factory, + * then we can recycle the object, and replace with newobject */ + if (!fs->fh_cache.is_same_partition(factory->fhk.fh_hk.object, fh.fh_hk.object)) { + return false; + } /* in the non-delete case, handle may still be in handle table */ if (fh_hook.is_linked()) { /* in this case, we are being called from a context which holds diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index d4a4d43be5a43..339e9829c5749 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -721,7 +721,7 @@ namespace rgw { void invalidate(); - bool reclaim() override; + bool reclaim(const cohort::lru::ObjectFactory* newobj_fac) override; typedef cohort::lru::LRU FhLRU;