git: 750d429a228f - main - vfs cache: further massage some commentary
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 08 Jul 2026 21:15:35 UTC
The branch main has been updated by mjg:
URL: https://cgit.FreeBSD.org/src/commit/?id=750d429a228fb102d6e5d45bdc116489acbfff00
commit 750d429a228fb102d6e5d45bdc116489acbfff00
Author: Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2026-07-08 21:13:34 +0000
Commit: Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2026-07-08 21:15:31 +0000
vfs cache: further massage some commentary
---
sys/kern/vfs_cache.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 66210bf58a7c..9e1c9cb757b5 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -6349,7 +6349,7 @@ cache_fplookup_impl(struct vnode *dvp, struct cache_fpl *fpl)
* Note: all VOP_FPLOOKUP_VEXEC routines have a comment referencing this one.
*
* Filesystems can opt in by setting the MNTK_FPLOOKUP flag and meeting criteria
- * outlined at the end.
+ * outlined at the end of this comment.
*
* Traversing from one vnode to another requires atomicity with regard to
* permissions, mount points and of course their relative placement (if you are
@@ -6370,6 +6370,13 @@ cache_fplookup_impl(struct vnode *dvp, struct cache_fpl *fpl)
* See places which issue vn_seqc_write_begin()/vn_seqc_write_end() for
* operations affected.
*
+ * Note: regardless of locked or unlocked operation atomicity of traversal only
+ * covers the immediate move from one vnode to the next. For example, suppose you
+ * are looking up "foo/level2/level3" and are racing against rename("foo", bar").
+ * If the vnode for "level2" was found and locked prior to the rename call locking
+ * "foo", then by the time "level3" is locked the true path might happen to be
+ * "bar/level2/level3".
+ *
* Suppose the variable "cnp" contains lookup metadata (the path etc.), then
* locked lookup conceptually looks like this:
*
@@ -6378,16 +6385,16 @@ cache_fplookup_impl(struct vnode *dvp, struct cache_fpl *fpl)
* for (;;) {
* // permission check
* if (!canlookup(dvp, cnp))
- * abort();
+ * fail();
* // look for the target name inside dvp
* tvp = findnext(dvp, cnp);
* vn_lock(tvp);
* // tvp is still guaranteed to be inside of dvp because of the lock on dvp
* vn_unlock(dvp);
- * // dvp is unlocked. its state is now arbitrary, but that's fine as we
+ * // dvp is unlocked and its state is now arbitrary, but that's fine as we
* // made the jump while everything relevant was correct, continue with tvp
* // as the directory to look up names in
- * tvp = dvp;
+ * dvp = tvp;
* if (last)
* break;
* // if not last loop back and continue until done
@@ -6395,7 +6402,8 @@ cache_fplookup_impl(struct vnode *dvp, struct cache_fpl *fpl)
* vget(tvp);
* return (tvp);
*
- * Lockless lookup replaces locking with sequence counter checks:
+ * Lockless lookup replaces locking with sequence counter checks. If any of
+ * them fail, it falls back to locked traversal.
*
* vfs_smr_enter();
* dvp_seqc = seqc_read_any(dvp);