git: 5f6df177758b - main - vfs: validate that vop vectors provide all or none fplookup vops
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 06 Apr 2023 15:45:35 UTC
The branch main has been updated by mjg:
URL: https://cgit.FreeBSD.org/src/commit/?id=5f6df177758b9dff88e4b6069aeb2359e8b0c493
commit 5f6df177758b9dff88e4b6069aeb2359e8b0c493
Author: Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2021-11-03 20:26:41 +0000
Commit: Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2023-04-06 15:20:41 +0000
vfs: validate that vop vectors provide all or none fplookup vops
In order to prevent later susprises.
---
sys/kern/vfs_cache.c | 34 ++++++++++++++++++++++++++++++++++
sys/sys/vnode.h | 1 +
sys/tools/vnode_if.awk | 2 ++
3 files changed, 37 insertions(+)
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index cc93158078d3..2ffa48f12299 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -3956,6 +3956,40 @@ static int cache_fast_lookup = 1;
#define CACHE_FPL_FAILED -2020
+void
+cache_vop_vector_register(struct vop_vector *v)
+{
+ size_t ops;
+
+ ops = 0;
+ if (v->vop_fplookup_vexec != NULL) {
+ ops++;
+ }
+ if (v->vop_fplookup_symlink != NULL) {
+ ops++;
+ }
+
+ if (ops == 2) {
+ return;
+ }
+
+ if (ops == 0) {
+ v->vop_fplookup_vexec = VOP_PANIC;
+ v->vop_fplookup_symlink = VOP_PANIC;
+ return;
+ }
+
+ printf("%s: invalid vop vector %p -- either all or none fplookup vops "
+ "need to be provided", __func__, v);
+ if (v->vop_fplookup_vexec == NULL) {
+ printf("%s: missing vop_fplookup_vexec\n", __func__);
+ }
+ if (v->vop_fplookup_symlink == NULL) {
+ printf("%s: missing vop_fplookup_symlink\n", __func__);
+ }
+ panic("bad vop vector %p", v);
+}
+
void
cache_fast_lookup_enabled_recalc(void)
{
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index a3eb00f0fe7c..2a62c6d1b659 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -650,6 +650,7 @@ int cache_symlink_resolve(struct cache_fpl *fpl, const char *string,
void cache_vop_rename(struct vnode *fdvp, struct vnode *fvp, struct vnode *tdvp,
struct vnode *tvp, struct componentname *fcnp, struct componentname *tcnp);
void cache_vop_rmdir(struct vnode *dvp, struct vnode *vp);
+void cache_vop_vector_register(struct vop_vector *);
#ifdef INVARIANTS
void cache_validate(struct vnode *dvp, struct vnode *vp,
struct componentname *cnp);
diff --git a/sys/tools/vnode_if.awk b/sys/tools/vnode_if.awk
index 415c33c52420..7fdaca208a9b 100644
--- a/sys/tools/vnode_if.awk
+++ b/sys/tools/vnode_if.awk
@@ -473,6 +473,8 @@ if (cfile) {
printc("\t\tpanic(\"%s: vop_vector %p already registered\",")
printc("\t\t __func__, orig_vop);");
printc("");
+ printc("\tcache_vop_vector_register(orig_vop);");
+ printc("");
for (name in funcarr) {
printc("\tvop = orig_vop;");
printc("\twhile (vop != NULL && \\");