Index: sys/fs/nfsserver/nfs_nfsdserv.c =================================================================== --- sys/fs/nfsserver/nfs_nfsdserv.c (revision 264251) +++ sys/fs/nfsserver/nfs_nfsdserv.c (working copy) @@ -1457,10 +1457,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1481,10 +1494,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1499,7 +1514,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1514,7 +1529,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1523,7 +1538,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret,