diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3243,28 +3243,35 @@ struct vnode **vpp, struct nfsexstuff *exp, struct mount **mpp, int startwrite) { - struct mount *mp; + struct mount *mp, *mpw; struct ucred *credanon; fhandle_t *fhp; + int error; + if (mpp != NULL) + *mpp = NULL; + *vpp = NULL; fhp = (fhandle_t *)nfp->nfsrvfh_data; - /* - * Check for the special case of the nfsv4root_fh. - */ mp = vfs_busyfs(&fhp->fh_fsid); - if (mpp != NULL) - *mpp = mp; if (mp == NULL) { - *vpp = NULL; nd->nd_repstat = ESTALE; goto out; } if (startwrite) { - vn_start_write(NULL, mpp, V_WAIT); + mpw = mp; + error = vn_start_write(NULL, &mpw, V_WAIT); + if (error != 0) { + mpw = NULL; + vfs_unbusy(mp); + nd->nd_repstat = ESTALE; + goto out; + } if (lktype == LK_SHARED && !(MNT_SHARED_WRITES(mp))) lktype = LK_EXCLUSIVE; - } + } else + mpw = NULL; + nd->nd_repstat = nfsvno_fhtovp(mp, fhp, nd->nd_nam, lktype, vpp, exp, &credanon); vfs_unbusy(mp); @@ -3276,6 +3283,7 @@ if (!nd->nd_repstat && exp->nes_exflag == 0 && !(nd->nd_flag & ND_NFSV4)) { vput(*vpp); + *vpp = NULL; nd->nd_repstat = EACCES; } @@ -3336,11 +3344,10 @@ if (credanon != NULL) crfree(credanon); if (nd->nd_repstat) { - if (startwrite) - vn_finished_write(mp); + vn_finished_write(mpw); *vpp = NULL; - if (mpp != NULL) - *mpp = NULL; + } else if (mpp != NULL) { + *mpp = mpw; } out: diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -612,8 +612,7 @@ nfsrvd_statstart(nfsv3to4op[nd->nd_procnum], /*now*/ NULL); nfsrvd_statend(nfsv3to4op[nd->nd_procnum], /*bytes*/ 0, /*now*/ NULL, /*then*/ NULL); - if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0) - vn_finished_write(mp); + vn_finished_write(mp); goto out; } @@ -643,8 +642,7 @@ error = (*(nfsrv3_procs0[nd->nd_procnum]))(nd, isdgram, vp, &nes); } - if (mp != NULL && nfsrv_writerpc[nd->nd_procnum] != 0) - vn_finished_write(mp); + vn_finished_write(mp); if (error == 0 && nd->nd_repstat == ERELOOKUP) { /*