git: 0b5bd1afd89f - main - cache: support lockless lookup of degenerate paths

Mateusz Guzik mjg at FreeBSD.org
Fri Jan 1 00:11:53 UTC 2021


The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=0b5bd1afd89fa42629a28dc01eae5e39c8e5fecd

commit 0b5bd1afd89fa42629a28dc01eae5e39c8e5fecd
Author:     Mateusz Guzik <mjguzik at gmail.com>
AuthorDate: 2020-12-28 06:53:17 +0000
Commit:     Mateusz Guzik <mjg at FreeBSD.org>
CommitDate: 2021-01-01 00:10:42 +0000

    cache: support lockless lookup of degenerate paths
    
    Tested by:      pho
---
 sys/kern/vfs_cache.c | 61 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index c9b0010020f8..cde2fde8a9ec 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -4224,6 +4224,56 @@ cache_fplookup_final(struct cache_fpl *fpl)
 	return (cache_fplookup_final_child(fpl, tvs));
 }
 
+/*
+ * Comment from locked lookup:
+ * Check for degenerate name (e.g. / or "") which is a way of talking about a
+ * directory, e.g. like "/." or ".".
+ */
+static int __noinline
+cache_fplookup_degenerate(struct cache_fpl *fpl)
+{
+	struct componentname *cnp;
+	struct vnode *dvp;
+	enum vgetstate dvs;
+	int error, lkflags;
+
+	fpl->tvp = fpl->dvp;
+	fpl->tvp_seqc = fpl->dvp_seqc;
+
+	cnp = fpl->cnp;
+	dvp = fpl->dvp;
+
+	if (__predict_false(cnp->cn_nameiop != LOOKUP)) {
+		cache_fpl_smr_exit(fpl);
+		return (cache_fpl_handled(fpl, EISDIR));
+	}
+
+	MPASS((cnp->cn_flags & SAVESTART) == 0);
+
+	if ((cnp->cn_flags & (LOCKPARENT|WANTPARENT)) != 0) {
+		return (cache_fplookup_final_withparent(fpl));
+	}
+
+	dvs = vget_prep_smr(dvp);
+	cache_fpl_smr_exit(fpl);
+	if (__predict_false(dvs == VGET_NONE)) {
+		return (cache_fpl_aborted(fpl));
+	}
+
+	if ((cnp->cn_flags & LOCKLEAF) != 0) {
+		lkflags = LK_SHARED;
+		if ((cnp->cn_flags & LOCKSHARED) == 0)
+			lkflags = LK_EXCLUSIVE;
+		error = vget_finish(dvp, lkflags, dvs);
+		if (__predict_false(error != 0)) {
+			return (cache_fpl_aborted(fpl));
+		}
+	} else {
+		vget_finish_ref(dvp, dvs);
+	}
+	return (cache_fpl_handled(fpl, 0));
+}
+
 static int __noinline
 cache_fplookup_noentry(struct cache_fpl *fpl)
 {
@@ -4694,15 +4744,8 @@ cache_fplookup_preparse(struct cache_fpl *fpl)
 	ndp = fpl->ndp;
 	cnp = fpl->cnp;
 
-	/*
-	 * TODO
-	 * Original comment:
-	 * Check for degenerate name (e.g. / or "")
-	 * which is a way of talking about a directory,
-	 * e.g. like "/." or ".".
-	 */
 	if (__predict_false(cnp->cn_nameptr[0] == '\0')) {
-		return (cache_fpl_aborted(fpl));
+		return (cache_fplookup_degenerate(fpl));
 	}
 
 	/*
@@ -4913,7 +4956,7 @@ cache_fplookup_impl(struct vnode *dvp, struct cache_fpl *fpl)
 	VNPASS(cache_fplookup_vnode_supported(fpl->dvp), fpl->dvp);
 
 	error = cache_fplookup_preparse(fpl);
-	if (__predict_false(error != 0)) {
+	if (__predict_false(cache_fpl_terminated(fpl))) {
 		goto out;
 	}
 


More information about the dev-commits-src-all mailing list