From 26b964875014a0d61f765428b1cb2768917f693c Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Fri, 7 Apr 2023 19:48:33 +0000 Subject: [PATCH] vfs: more informative panic for missing fplookup ops --- sys/kern/vfs_cache.c | 40 ++++++++++++++++++++++++++++++++++++++-- sys/kern/vfs_subr.c | 5 +---- sys/sys/vnode.h | 6 ++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 2ffa48f12299..294f7740dacf 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -3956,6 +3956,20 @@ static int cache_fast_lookup = 1; #define CACHE_FPL_FAILED -2020 +static int +cache_vop_bad_vexec(struct vop_fplookup_vexec_args *v) +{ + vn_printf(v->a_vp, "no proper vop_fplookup_vexec\n"); + panic("no proper vop_fplookup_vexec"); +} + +static int +cache_vop_bad_symlink(struct vop_fplookup_symlink_args *v) +{ + vn_printf(v->a_vp, "no proper vop_fplookup_symlink\n"); + panic("no proper vop_fplookup_symlink"); +} + void cache_vop_vector_register(struct vop_vector *v) { @@ -3974,8 +3988,8 @@ cache_vop_vector_register(struct vop_vector *v) } if (ops == 0) { - v->vop_fplookup_vexec = VOP_PANIC; - v->vop_fplookup_symlink = VOP_PANIC; + v->vop_fplookup_vexec = cache_vop_bad_vexec; + v->vop_fplookup_symlink = cache_vop_bad_symlink; return; } @@ -3990,6 +4004,28 @@ cache_vop_vector_register(struct vop_vector *v) panic("bad vop vector %p", v); } +#ifdef INVARIANTS +void +cache_validate_vop_vector(struct mount *mp, struct vop_vector *vops) +{ + if (mp == NULL) + return; + + if ((mp->mnt_kern_flag & MNTK_FPLOOKUP) == 0) + return; + + if (vops->vop_fplookup_vexec == NULL || + vops->vop_fplookup_vexec == cache_vop_bad_vexec) + panic("bad vop_fplookup_vexec on vector %p for filesystem %s", + vops, mp->mnt_vfc->vfc_name); + + if (vops->vop_fplookup_symlink == NULL || + vops->vop_fplookup_symlink == cache_vop_bad_symlink) + panic("bad vop_fplookup_symlink on vector %p for filesystem %s", + vops, mp->mnt_vfc->vfc_name); +} +#endif + void cache_fast_lookup_enabled_recalc(void) { diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 96adc6ff3493..1da299e93eea 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1800,10 +1800,7 @@ getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops, KASSERT(vops->registered, ("%s: not registered vector op %p\n", __func__, vops)); - if (mp != NULL && (mp->mnt_kern_flag & MNTK_FPLOOKUP) != 0) { - MPASS(vops->vop_fplookup_vexec != VOP_PANIC); - MPASS(vops->vop_fplookup_symlink != VOP_PANIC); - } + cache_validate_vop_vector(mp, vops); td = curthread; if (td->td_vp_reserved != NULL) { diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 2a62c6d1b659..74514654713a 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -654,6 +654,7 @@ void cache_vop_vector_register(struct vop_vector *); #ifdef INVARIANTS void cache_validate(struct vnode *dvp, struct vnode *vp, struct componentname *cnp); +void cache_validate_vop_vector(struct mount *mp, struct vop_vector *vops); void cache_assert_no_entries(struct vnode *vp); #else static inline void @@ -661,6 +662,11 @@ cache_validate(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) { } +static inline void +cache_validate_vop_vector(struct mount *mp, struct vop_vector *vops) +{ +} + static inline void cache_assert_no_entries(struct vnode *vp) {