/* public flag values */
constexpr uint32_t FLAG_NONE = 0x0000;
constexpr uint32_t FLAG_INITIAL = 0x0001;
+ constexpr uint32_t FLAG_RECYCLE = 0x0002;
enum class Edge : std::uint8_t
{
delete tdo;
} /* unref */
- Object* insert(ObjectFactory* fac, Edge edge, uint32_t flags) {
+ 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();
- if (o)
+ if (o) {
fac->recycle(o); /* recycle existing object */
+ flags |= FLAG_RECYCLE;
+ }
else
o = fac->alloc(); /* get a new one */
}
RGWFileHandle::~RGWFileHandle() {
- /* in the non-delete case, handle may still be in handle table */
- if (fh_hook.is_linked()) {
- fs->fh_cache.remove(fh.fh_hk.object, this, FHCache::FLAG_LOCK);
- }
/* cond-unref parent */
if (parent && (! parent->is_mount())) {
/* safe because if parent->unref causes its deletion,
lsubdout(fs->get_context(), rgw, 17)
<< __func__ << " " << *this
<< dendl;
- /* remove if still in fh_cache */
+ /* in the non-delete case, handle may still be in handle table */
if (fh_hook.is_linked()) {
- fs->fh_cache.remove(fh.fh_hk.object, this, FHCache::FLAG_LOCK);
+ /* in this case, we are being called from a context which holds
+ * the partition lock */
+ fs->fh_cache.remove(fh.fh_hk.object, this, FHCache::FLAG_NONE);
}
return true;
} /* RGWFileHandle::reclaim */
/* make or re-use handle */
RGWFileHandle::Factory prototype(this, parent, fhk,
obj_name, CREATE_FLAGS(flags));
+ uint32_t iflags{cohort::lru::FLAG_INITIAL};
fh = static_cast<RGWFileHandle*>(
fh_lru.insert(&prototype,
cohort::lru::Edge::MRU,
- cohort::lru::FLAG_INITIAL));
+ iflags));
if (fh) {
/* lock fh (LATCHED) */
if (flags & RGWFileHandle::FLAG_LOCK)
fh->mtx.lock();
- /* inserts, releasing latch */
- fh_cache.insert_latched(fh, lat, RGWFileHandle::FHCache::FLAG_UNLOCK);
+ if (likely(! (iflags & cohort::lru::FLAG_RECYCLE))) {
+ /* inserts at cached insert iterator, releasing latch */
+ fh_cache.insert_latched(
+ fh, lat, RGWFileHandle::FHCache::FLAG_UNLOCK);
+ } else {
+ /* recycle step invalidates Latch */
+ fh_cache.insert(
+ fhk.fh_hk.object, fh, RGWFileHandle::FHCache::FLAG_NONE);
+ lat.lock->unlock(); /* !LATCHED */
+ }
get<1>(fhr) |= RGWFileHandle::FLAG_CREATE;
/* ref parent (non-initial ref cannot fail on valid object) */
if (! parent->is_mount()) {