From owner-freebsd-current Thu Jul 29 20:42:53 1999 Delivered-To: freebsd-current@freebsd.org Received: from apollo.backplane.com (apollo.backplane.com [209.157.86.2]) by hub.freebsd.org (Postfix) with ESMTP id BC6A214EBC; Thu, 29 Jul 1999 20:42:51 -0700 (PDT) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.9.3/8.9.1) id UAA81494; Thu, 29 Jul 1999 20:42:40 -0700 (PDT) (envelope-from dillon) Date: Thu, 29 Jul 1999 20:42:40 -0700 (PDT) From: Matthew Dillon Message-Id: <199907300342.UAA81494@apollo.backplane.com> To: "Brian F. Feldman" Cc: Bill Paul , peter@netplex.com.au, crossd@cs.rpi.edu, current@FreeBSD.ORG Subject: Re: readdirplus client side fix (was Re: IRIX 6.5.4 NFS v3 TCP client + FreeBSD server = bewm) References: Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG :It's not hard. vput() VOP_UNLOCK()s a vnode and then vrele() (opposite of :vref())'s it (decreases v_usecount, I believe.) So when a file system :is mounted, with these bugs, the locked vnodes are never unlocked. :The unmount call will end up sleeping with the state "vnlock" waiting for :the operation that has the vnode in question vref()d to vrele() and :let go of it. : :At least, that's how it looks to me, but I never really looked at vnode :code until today. : : Brian Fundakowski Feldman _ __ ___ ____ ___ ___ ___ : green@FreeBSD.org _ __ ___ | _ ) __| \ : FreeBSD: The Power to Serve! _ __ | _ \._ \ |) | : http://www.FreeBSD.org/ _ |___/___/___/ Basically, yes. The NFS code is a morass no matter what. Here's a full explanation: readdirplus is like readdir except it returns stat info along with the directory entries, since most NFS clients will stat the files it picks up scanning a directory. In order to accomplish this, the underlying vnode representing each directory entry is retrieved and locked. However, there is a special case: We *already* have a reference on the directory vnode itself, and one of the directory entries, ".", will be the same vnode. Our reference vnode, vp is *NOT* locked. In fact, we *can't* lock it without creating a potential deadlock situation (at least that is my take). Ok, so while scanning the directory we generate 'newvp' vnode pointers. If the directory entry is "." the newvp == vp (vp is the parent directory), and there is no lock on the vp, only a reference. If newvp != vp then it is a directory entry other then "." and newvp is both referenced *and* locked. When we are through retrieving the stat info from newvp, we have to release it. We either have to release and unlock newvp, or we simply have to release it depending on whether it was locked or not. vrele() will release a vnode without messing with any locks. vput() will release and unlock a vnode. Hence the complexity: if (newvp == vp) vrele(newvp); else; vput(newvp); -Matt Matthew Dillon To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message