All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ceph: drop negtive child dentries before try pruning inode's alias
@ 2017-11-30 14:12 Yan, Zheng
  2017-11-30 14:37 ` Jeff Layton
  2017-12-04 15:25 ` Jeff Layton
  0 siblings, 2 replies; 7+ messages in thread
From: Yan, Zheng @ 2017-11-30 14:12 UTC (permalink / raw)
  To: ceph-devel; +Cc: jlayton, Yan, Zheng

negtive child dentry holds reference on inode's alias, it makes
d_prune_aliases() do nothing.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
---
 fs/ceph/mds_client.c | 43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index da181acd4a61..9e7bb5fa9295 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -1440,6 +1440,30 @@ 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_negtive = 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_negtive = false;
+			break;
+		}
+	}
+	spin_unlock(&dentry->d_lock);
+
+	if (all_negtive)
+		shrink_dcache_parent(dentry);
+out:
+	dput(dentry);
+	return all_negtive;
+}
+
 /*
  * Trim old(er) caps.
  *
@@ -1495,15 +1519,20 @@ static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
 		__ceph_remove_cap(cap, true);
 		session->s_trim_caps--;
 	} else {
-		int refs;
+		struct dentry *dentry;
 		/* try dropping referring dentries */
 		spin_unlock(&ci->i_ceph_lock);
-		d_prune_aliases(inode);
-		refs = atomic_read(&inode->i_count);
-		if (refs == 1)
-			session->s_trim_caps--;
-		dout("trim_caps_cb %p cap %p  pruned, count now %d\n",
-		     inode, cap, refs);
+		dentry = d_find_any_alias(inode);
+		/* drop_negative_children() calls dput() */
+		if (dentry && drop_negative_children(dentry)) {
+			int refs;
+			d_prune_aliases(inode);
+			refs = atomic_read(&inode->i_count);
+			if (refs == 1)
+				session->s_trim_caps--;
+			dout("trim_caps_cb %p cap %p pruned, count now %d\n",
+			     inode, cap, refs);
+		}
 		return 0;
 	}
 
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-12-08  7:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-11-30 14:12 [PATCH] ceph: drop negtive child dentries before try pruning inode's alias Yan, Zheng
2017-11-30 14:37 ` Jeff Layton
2017-12-01  1:07   ` Yan, Zheng
2017-12-04 15:25 ` Jeff Layton
2017-12-07 13:21   ` Ilya Dryomov
2017-12-07 20:42     ` Jeff Layton
2017-12-08  7:32     ` Yan, Zheng

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.