From 8495165c3d5ff3167e1e3e77ade95af4be6b3895 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Wed, 8 Sep 2021 13:06:12 -0500 Subject: [PATCH] FBSD: Use vrefl() when available Commit 81ea6544 (FBSD: avoid vrefl()) removed our reference to vrefl(), since it was only introduced with FreeBSD 11.0. However, it was replaced with calls to vref() and vrele(), the latter of which can lock the vnode, and generally is allowed to sleep. Many osi_vnhold callers hold AFS_GLOCK, which is a non-sleepable lock, so this can cause a panic if the vnode is VI_DOOMED and locked by another thread. To avoid this on at least modern FreeBSD releases, use vrefl() when it is available (since ). Change-Id: I535af9d58380bb1fd108b8a953b6c26a1c818d94 Reviewed-on: https://gerrit.openafs.org/14796 Tested-by: BuildBot Reviewed-by: Michael Meffie Reviewed-by: Andrew Deason --- src/afs/FBSD/osi_vcache.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/afs/FBSD/osi_vcache.c b/src/afs/FBSD/osi_vcache.c index 7c0e21b3f2..7b5888eb30 100644 --- a/src/afs/FBSD/osi_vcache.c +++ b/src/afs/FBSD/osi_vcache.c @@ -13,6 +13,12 @@ #include "afs/sysincludes.h" /*Standard vendor system headers */ #include "afsincludes.h" /*AFS-based standard headers */ +#if __FreeBSD_version >= 1100095 +# define HAVE_VREFL 1 +#else +# define HAVE_VREFL 0 +#endif + int osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { @@ -126,6 +132,24 @@ osi_PostPopulateVCache(struct vcache *avc) vSetType(avc, VREG); } +#if HAVE_VREFL +int +osi_vnhold(struct vcache *avc) +{ + struct vnode *vp = AFSTOV(avc); + + VI_LOCK(vp); + if ((vp->v_iflag & VI_DOOMED) != 0) { + VI_UNLOCK(vp); + return ENOENT; + } + + vrefl(vp); + + VI_UNLOCK(vp); + return 0; +} +#else int osi_vnhold(struct vcache *avc) { @@ -142,3 +166,4 @@ osi_vnhold(struct vcache *avc) VI_UNLOCK(vp); return 0; } +#endif /* HAVE_VREFL */