From: Yan, Zheng Date: Fri, 26 Dec 2014 08:27:25 +0000 (+0800) Subject: client: close dirfrag when trying to trim an inode X-Git-Tag: v0.92~60^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6e67450015158b324154bbfdf2a3444186a605e9;p=ceph.git client: close dirfrag when trying to trim an inode Fixes: #10387 Signed-off-by: Yan, Zheng --- diff --git a/src/client/Client.cc b/src/client/Client.cc index cd3ae55b9b90..b69cc8a03b1b 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -4145,8 +4145,24 @@ void Client::_schedule_invalidate_dentry_callback(Dentry *dn, bool del) async_dentry_invalidator.queue(new C_Client_DentryInvalidate(this, dn, del)); } -void Client::_invalidate_inode_parents(Inode *in) +void Client::_try_to_trim_inode(Inode *in) { + int ref = in->get_num_ref(); + + if (in->dir && !in->dir->dentry_list.empty()) { + for (xlist::iterator p = in->dir->dentry_list.begin(); + !p.end(); ) { + Dentry *dn = *p; + ++p; + if (dn->lru_is_expireable()) + unlink(dn, false, false); // close dir, drop dentry + } + --ref; + } + // make sure inode was not freed when closing dir + if (ref == 0) + return; + set::iterator q = in->dn_set.begin(); while (q != in->dn_set.end()) { Dentry *dn = *q++; @@ -4291,7 +4307,7 @@ void Client::handle_cap_grant(MetaSession *session, Inode *in, Cap *cap, MClient // may drop inode's last ref if (deleted_inode) - _invalidate_inode_parents(in); + _try_to_trim_inode(in); m->put(); } diff --git a/src/client/Client.h b/src/client/Client.h index 0cb4c20bc112..7e5574852543 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -546,7 +546,7 @@ protected: void _schedule_invalidate_dentry_callback(Dentry *dn, bool del); void _async_dentry_invalidate(vinodeno_t dirino, vinodeno_t ino, string& name); - void _invalidate_inode_parents(Inode *in); + void _try_to_trim_inode(Inode *in); void _schedule_invalidate_callback(Inode *in, int64_t off, int64_t len, bool keep_caps); void _invalidate_inode_cache(Inode *in);