} while (! (stop || shutdown));
} /* RGWLibFS::gc */
+ RGWFileHandle::~RGWFileHandle() {
+ if (parent && (! parent->is_root())) {
+ /* safe because if parent->unref causes its deletion,
+ * there are a) by refcnt, no other objects/paths pointing
+ * to it and b) by the semantics of valid iteration of
+ * fh_lru (observed, e.g., by cohort_lru<T,...>::drain())
+ * no unsafe iterators reaching it either--n.b., this constraint
+ * is binding oncode which may in future attempt to e.g.,
+ * cause the eviction of objects in LRU order */
+ (void) get_fs()->fh_lru.unref(parent, cohort::lru::FLAG_NONE);
+ }
+ }
+
void RGWFileHandle::encode_attrs(ceph::buffer::list& ux_key1,
ceph::buffer::list& ux_attrs1)
{
typedef cohort::lru::TreeX<RGWFileHandle, FhTree, FhLT, FhEQ, fh_key,
std::mutex> FHCache;
- virtual ~RGWFileHandle() {}
+ virtual ~RGWFileHandle();
class Factory : public cohort::lru::ObjectFactory
{
/* inserts, releasing latch */
fh_cache.insert_latched(fh, lat, RGWFileHandle::FHCache::FLAG_UNLOCK);
get<1>(fhr) |= RGWFileHandle::FLAG_CREATE;
+ /* ref parent (non-initial ref cannot fail on valid object) */
+ if (! parent->is_root()) {
+ (void) fh_lru.ref(parent, cohort::lru::FLAG_NONE);
+ }
goto out; /* !LATCHED */
} else {
lat.lock->unlock();