In nfsrv_readdirplus() function we call VFS_VGET() without protection against unmount, so we can use dead vp->v_mount. Fix this by busying mountpoint before dropping vnode lock. Index: nfs_serv.c =================================================================== --- nfs_serv.c (wersja 216565) +++ nfs_serv.c (kopia robocza) @@ -3044,6 +3044,7 @@ int v3 = (nfsd->nd_flag & ND_NFSV3); int usevget = 1, vfslocked; struct componentname cn; + struct mount *mntp = NULL; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); vfslocked = 0; @@ -3100,8 +3101,21 @@ error = 0; goto nfsmout; } + mntp = vp->v_mount; + vfs_ref(mntp); VOP_UNLOCK(vp, 0); vp_locked = 0; + error = vfs_busy(mntp, 0); + vfs_rel(mntp); + if (error) { + mntp = NULL; + vrele(vp); + vp = NULL; + nfsm_reply(NFSX_V3POSTOPATTR); + nfsm_srvpostop_attr(error, &at); + error = 0; + goto nfsmout; + } rbuf = malloc(siz, M_TEMP, M_WAITOK); again: iv.iov_base = rbuf; @@ -3215,8 +3229,8 @@ * For readdir_and_lookup get the vnode using * the file number. */ - error = VFS_VGET(vp->v_mount, dp->d_fileno, - LK_SHARED, &nvp); + error = VFS_VGET(mntp, dp->d_fileno, LK_SHARED, + &nvp); if (error != 0 && error != EOPNOTSUPP) { error = 0; goto invalid; @@ -3375,6 +3389,8 @@ nfsmout: if (vp) vrele(vp); + if (mntp) + vfs_unbusy(mntp); VFS_UNLOCK_GIANT(vfslocked); return(error); }