mirror of
https://github.com/ceph/ceph
synced 2025-01-11 21:50:26 +00:00
rgw_file: interned RGWFileHandle objects need parent refs
RGW NFS fhcache/RGWFileHandle operators assume existence of the full chain of parents from any object to the its fs_root--this is a consequence of the weakly-connected namespace design goal, and not a defect. This change ensures the invariant by taking a parent ref when objects are interned (when a parent ref is guaranteed). Parent refs are returned when objects are destroyed--essentially by the invariant, such a ref must exist. The extra ref is omitted when parent->is_root(), as that node is not in the LRU cache. Fixes: http://tracker.ceph.com/issues/18650 Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
This commit is contained in:
parent
748f0a6fb9
commit
0e5299f3f4
@ -716,6 +716,19 @@ namespace rgw {
|
||||
} 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)
|
||||
{
|
||||
|
@ -640,7 +640,7 @@ namespace rgw {
|
||||
typedef cohort::lru::TreeX<RGWFileHandle, FhTree, FhLT, FhEQ, fh_key,
|
||||
std::mutex> FHCache;
|
||||
|
||||
virtual ~RGWFileHandle() {}
|
||||
virtual ~RGWFileHandle();
|
||||
|
||||
class Factory : public cohort::lru::ObjectFactory
|
||||
{
|
||||
@ -958,6 +958,10 @@ namespace rgw {
|
||||
/* 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();
|
||||
|
Loading…
Reference in New Issue
Block a user