From c328486f246f100ac4fc23c9337f2cbb92d28105 Mon Sep 17 00:00:00 2001 From: John Spray Date: Wed, 3 Sep 2014 02:00:33 +0100 Subject: [PATCH] client: fix crash in trim_caps In a75af4c2, procedure was added to invalidate root's dentries if the trimming failed to free enough caps. This would sometimes crash because root->dir wasn't necessarily open. Fix by only doing it if root dir is open, though I suspect this may not be the end of it... Signed-off-by: John Spray --- src/client/Client.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 667b700b004..d749dd05a38 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3171,10 +3171,12 @@ void Client::trim_caps(MetaSession *s, int max) set::iterator q = in->dn_set.begin(); while (q != in->dn_set.end()) { Dentry *dn = *q++; - if (dn->lru_is_expireable()) + if (dn->lru_is_expireable()) { trim_dentry(dn); - else + } else { + ldout(cct, 20) << " not expirable: " << dn->name << dendl; all = false; + } } if (all) trimmed++; @@ -3191,11 +3193,17 @@ void Client::trim_caps(MetaSession *s, int max) // notify kernel to invalidate top level directory entries. As a side effect, // unused inodes underneath these entries get pruned. if (dentry_invalidate_cb && s->caps.size() > max) { - for (ceph::unordered_map::iterator p = root->dir->dentries.begin(); - p != root->dir->dentries.end(); - ++p) { - if (p->second->inode) - _schedule_invalidate_dentry_callback(p->second, false); + assert(root); + if (root->dir) { + for (ceph::unordered_map::iterator p = root->dir->dentries.begin(); + p != root->dir->dentries.end(); + ++p) { + if (p->second->inode) + _schedule_invalidate_dentry_callback(p->second, false); + } + } else { + // This seems unnatural, as long as we are holding caps they must be on + // some descendent of the root, so why don't we have the root open? } } } -- 2.47.3