From 41c59a2d341f9e18184b6d5c47fd99e30bf25639 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Tue, 9 Feb 2010 00:59:42 -0800 Subject: [PATCH] kernel - NFS - fix deadlock in NFS client-side readdirplus (part 2) * Missed a vnode in the last commit. Two vnodes have to potentially be unlocked. --- sys/vfs/nfs/nfs_vnops.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index c68ff67041..ddbc2fc8bd 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -2655,15 +2655,17 @@ nfs_readdirplusrpc_uio(struct vnode *vp, struct uio *uiop) nlc.nlc_nameptr); #endif /* - * Work around a directory-vp/namecache - * deadlock. Namecache lookups should - * be run without any vp locks held. + * Work around a vp/namecache deadlock. + * Namecache lookups should be run + * without any vp locks held. */ lkstatus = vn_islocked(vp); if (lkstatus == LK_EXCLUSIVE || lkstatus == LK_SHARED) { vn_unlock(vp); } + if (newvp != vp) + vn_unlock(newvp); nch = cache_nlookup(&dnch, &nlc); cache_setunresolved(&nch); nfs_cache_setvp(&nch, newvp, @@ -2673,6 +2675,8 @@ nfs_readdirplusrpc_uio(struct vnode *vp, struct uio *uiop) lkstatus == LK_SHARED) { vn_lock(vp, lkstatus | LK_RETRY); } + if (newvp != vp) + vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY); } else { kprintf("Warning: NFS/rddirplus, " "UNABLE TO ENTER %*.*s\n", -- 2.41.0