Loading fs/ceph/mds_client.c +38 −4 Original line number Diff line number Diff line Loading @@ -1440,6 +1440,29 @@ static int __close_session(struct ceph_mds_client *mdsc, return request_close_session(mdsc, session); } static bool drop_negative_children(struct dentry *dentry) { struct dentry *child; bool all_negative = true; if (!d_is_dir(dentry)) goto out; spin_lock(&dentry->d_lock); list_for_each_entry(child, &dentry->d_subdirs, d_child) { if (d_really_is_positive(child)) { all_negative = false; break; } } spin_unlock(&dentry->d_lock); if (all_negative) shrink_dcache_parent(dentry); out: return all_negative; } /* * Trim old(er) caps. * Loading Loading @@ -1490,16 +1513,27 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) if ((used | wanted) & ~oissued & mine) goto out; /* we need these caps */ session->s_trim_caps--; if (oissued) { /* we aren't the only cap.. just remove us */ __ceph_remove_cap(cap, true); session->s_trim_caps--; } else { struct dentry *dentry; /* try dropping referring dentries */ spin_unlock(&ci->i_ceph_lock); dentry = d_find_any_alias(inode); if (dentry && drop_negative_children(dentry)) { int count; dput(dentry); d_prune_aliases(inode); count = atomic_read(&inode->i_count); if (count == 1) session->s_trim_caps--; dout("trim_caps_cb %p cap %p pruned, count now %d\n", inode, cap, atomic_read(&inode->i_count)); inode, cap, count); } else { dput(dentry); } return 0; } Loading Loading
fs/ceph/mds_client.c +38 −4 Original line number Diff line number Diff line Loading @@ -1440,6 +1440,29 @@ static int __close_session(struct ceph_mds_client *mdsc, return request_close_session(mdsc, session); } static bool drop_negative_children(struct dentry *dentry) { struct dentry *child; bool all_negative = true; if (!d_is_dir(dentry)) goto out; spin_lock(&dentry->d_lock); list_for_each_entry(child, &dentry->d_subdirs, d_child) { if (d_really_is_positive(child)) { all_negative = false; break; } } spin_unlock(&dentry->d_lock); if (all_negative) shrink_dcache_parent(dentry); out: return all_negative; } /* * Trim old(er) caps. * Loading Loading @@ -1490,16 +1513,27 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg) if ((used | wanted) & ~oissued & mine) goto out; /* we need these caps */ session->s_trim_caps--; if (oissued) { /* we aren't the only cap.. just remove us */ __ceph_remove_cap(cap, true); session->s_trim_caps--; } else { struct dentry *dentry; /* try dropping referring dentries */ spin_unlock(&ci->i_ceph_lock); dentry = d_find_any_alias(inode); if (dentry && drop_negative_children(dentry)) { int count; dput(dentry); d_prune_aliases(inode); count = atomic_read(&inode->i_count); if (count == 1) session->s_trim_caps--; dout("trim_caps_cb %p cap %p pruned, count now %d\n", inode, cap, atomic_read(&inode->i_count)); inode, cap, count); } else { dput(dentry); } return 0; } Loading