: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      _ __ ___ ____  ___ ___ ___  
: [EMAIL PROTECTED]                   _ __ ___ | _ ) __|   \ 
:     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 
                                        <[EMAIL PROTECTED]>


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to