From f069164876713037b41d4fe2fdc798eabe83fd3e Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Fri, 30 Jul 1999 04:02:04 +0000 Subject: [PATCH] Fix two bugs in nfs_readdirplus(). The first is that in some cases, vnodes are locked and never unlocked, which leads to processes starting to wedge up after doing a mount -o nfsv3,tcp,rdirplus foo:/fs /fs; ls /fs. The second is that sometimes cnp is accessed without having been properly initialized: cnp->cn_nameptr points to an earlier name while "len" contains the length of a current name of different size. This leads to an attempt to dereference *(cn->cn_nameptr + len) which will sometimes cause a page fault and a panic. With these two fixes, client side readdirplus works correctly with FreeBSD, IRIX 6.5.4 and Solaris 2.5.1 and 2.6 servers. Submitted by: Matthew Dillon --- sys/nfs/nfs_vnops.c | 9 ++++++--- sys/nfsclient/nfs_vnops.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index d95ed0ac8e4..72e67f6837c 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $Id: nfs_vnops.c,v 1.134 1999/06/30 02:53:51 julian Exp $ + * $Id: nfs_vnops.c,v 1.135 1999/07/01 13:32:54 peter Exp $ */ @@ -2343,7 +2343,7 @@ nfs_readdirplusrpc(vp, uiop, cred) newvp = NFSTOV(np); } } - if (doit) { + if (doit && bigenough) { dpossav2 = dpos; dpos = dpossav1; mdsav2 = md; @@ -2367,7 +2367,10 @@ nfs_readdirplusrpc(vp, uiop, cred) nfsm_adv(nfsm_rndup(i)); } if (newvp != NULLVP) { - vrele(newvp); + if (newvp == vp) + vrele(newvp); + else + vput(newvp); newvp = NULLVP; } nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index d95ed0ac8e4..72e67f6837c 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - * $Id: nfs_vnops.c,v 1.134 1999/06/30 02:53:51 julian Exp $ + * $Id: nfs_vnops.c,v 1.135 1999/07/01 13:32:54 peter Exp $ */ @@ -2343,7 +2343,7 @@ nfs_readdirplusrpc(vp, uiop, cred) newvp = NFSTOV(np); } } - if (doit) { + if (doit && bigenough) { dpossav2 = dpos; dpos = dpossav1; mdsav2 = md; @@ -2367,7 +2367,10 @@ nfs_readdirplusrpc(vp, uiop, cred) nfsm_adv(nfsm_rndup(i)); } if (newvp != NULLVP) { - vrele(newvp); + if (newvp == vp) + vrele(newvp); + else + vput(newvp); newvp = NULLVP; } nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);