DF-2994 / fix.diff
--- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -571,12 +571,20 @@ nfsrv_lookup(struct nfsrv_descript *nfsd if (error == 0) { /* * Found an index file. Get rid of * the old references. transfer vp and * load up the new vp. Fortunately we do * not have to deal with dvp, that would * be a huge mess. */ if (dirp) vrele(dirp); dirp = vp; vp = NULL; error = cache_vget(&nd.nl_nch, nd.nl_cred, LK_EXCLUSIVE, &vp); KKASSERT(error == 0); + } else { + /* + * DF-2994: the index lookup failed, so we + * continue with the original vp — which was + * unlocked above. Restore its lock so the + * vput() paths below cannot release an + * unheld lock (guaranteed panic). + */ + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } error = 0; } |