nfsd: Fix handling of the error case for nfsvno_open some more

Commit ded5f2954e defined done_namei to indicate that
nd_repstat was set after a successful nfsvno_namei(),
so that a cleanup needs to be done in nfsvno_open().
However, it missed the case where a call to
nfsrv_opencheck() in nfsvno_open() sets nd_repstat non-zero.

This would cause panics due to a dangling locked vnode
when nfsrv_opencheck() set nd_repstat, such as during grace
just after a server boot.

This patch fixes the problem.

PR:	268971
This commit is contained in:
Rick Macklem 2023-02-10 19:34:57 -08:00
parent c92790b3fb
commit 3e230e0cc4

View File

@ -1842,10 +1842,19 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
u_quad_t tempsize;
struct nfsexstuff nes;
struct thread *p = curthread;
uint32_t oldrepstat;
if (ndp->ni_vp == NULL)
if (ndp->ni_vp == NULL) {
/*
* If nfsrv_opencheck() sets nd_repstat, done_namei needs to be
* set true, since cleanup after nfsvno_namei() is needed.
*/
oldrepstat = nd->nd_repstat;
nd->nd_repstat = nfsrv_opencheck(clientid,
stateidp, stp, NULL, nd, p, nd->nd_repstat);
if (nd->nd_repstat != 0 && oldrepstat == 0)
done_namei = true;
}
if (!nd->nd_repstat) {
if (ndp->ni_vp == NULL) {
nd->nd_repstat = VOP_CREATE(ndp->ni_dvp,