Author: kib
Date: Tue Jun 23 10:47:42 2009
New Revision: 194693
URL: http://svn.freebsd.org/changeset/base/194693

Log:
  MFC r192683:
  In lf_advlockasync(), recheck for doomed vnode after the state->ls_lock
  is acquired. In the lf_purgelocks(), assert that vnode is doomed and set
  *statep to NULL before clearing ls_pending list. Otherwise, we allow for
  the thread executing lf_advlockasync() to put new pending entry after
  state->ls_lock is dropped in lf_purgelocks().
  
  MFC r193931:
  Do not leak the state->ls_lock after VI_DOOMED check introduced
  in the r192683.
  
  MFC r194356:
  Decrement state->ls_threads when vnode appeared to be doomed.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/kern/kern_lockf.c

Modified: stable/7/sys/kern/kern_lockf.c
==============================================================================
--- stable/7/sys/kern/kern_lockf.c      Tue Jun 23 10:41:38 2009        
(r194692)
+++ stable/7/sys/kern/kern_lockf.c      Tue Jun 23 10:47:42 2009        
(r194693)
@@ -633,7 +633,23 @@ lf_advlockasync(struct vop_advlockasync_
        }
 
        sx_xlock(&state->ls_lock);
-       switch(ap->a_op) {
+       /*
+        * Recheck the doomed vnode after state->ls_lock is
+        * locked. lf_purgelocks() requires that no new threads add
+        * pending locks when vnode is marked by VI_DOOMED flag.
+        */
+       VI_LOCK(vp);
+       if (vp->v_iflag & VI_DOOMED) {
+               state->ls_threads--;
+               wakeup(state);
+               VI_UNLOCK(vp);
+               sx_xunlock(&state->ls_lock);
+               lf_free_lock(lock);
+               return (ENOENT);
+       }
+       VI_UNLOCK(vp);
+
+       switch (ap->a_op) {
        case F_SETLK:
                error = lf_setlock(state, lock, vp, ap->a_cookiep);
                break;
@@ -755,8 +771,11 @@ lf_purgelocks(struct vnode *vp, struct l
         * the remaining locks.
         */
        VI_LOCK(vp);
+       KASSERT(vp->v_iflag & VI_DOOMED,
+           ("lf_purgelocks: vp %p has not vgone yet", vp));
        state = *statep;
        if (state) {
+               *statep = NULL;
                state->ls_threads++;
                VI_UNLOCK(vp);
 
@@ -789,7 +808,6 @@ lf_purgelocks(struct vnode *vp, struct l
                VI_LOCK(vp);
                while (state->ls_threads > 1)
                        msleep(state, VI_MTX(vp), 0, "purgelocks", 0);
-               *statep = 0;
                VI_UNLOCK(vp);
 
                /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to