From: John Spray Date: Wed, 3 Sep 2014 18:31:38 +0000 (+0100) Subject: client: fix potentially invalid read in trim_caps X-Git-Tag: v0.86~68^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=21f5e18ee39845109bc10722757032700eda027a;p=ceph.git client: fix potentially invalid read in trim_caps trim_dentry can potentially free an inode, so get/put it around the block where we use the inode's dn_set. Signed-off-by: John Spray --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 840b55257a94..ae4df6765120 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3170,10 +3170,12 @@ void Client::trim_caps(MetaSession *s, int max) ldout(cct, 20) << " trying to trim dentries for " << *in << dendl; bool all = true; set::iterator q = in->dn_set.begin(); + in->get(); while (q != in->dn_set.end()) { Dentry *dn = *q++; if (dn->lru_is_expireable()) { trim_dentry(dn); + } else { ldout(cct, 20) << " not expirable: " << dn->name << dendl; all = false; @@ -3183,6 +3185,8 @@ void Client::trim_caps(MetaSession *s, int max) ldout(cct, 20) << __func__ << " counting as trimmed: " << *in << dendl; trimmed++; } + + put_inode(in); } ++p; @@ -3193,6 +3197,7 @@ void Client::trim_caps(MetaSession *s, int max) } s->s_cap_iterator = NULL; + // 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) {