Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Jun 2009 10:47:42 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r194693 - in stable/7/sys: . contrib/pf kern
Message-ID:  <200906231047.n5NAlgnS073670@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 
 		/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906231047.n5NAlgnS073670>