Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 May 2009 12:33:16 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r192683 - head/sys/kern
Message-ID:  <200905241233.n4OCXGkd089814@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sun May 24 12:33:16 2009
New Revision: 192683
URL: http://svn.freebsd.org/changeset/base/192683

Log:
  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().
  
  Reviewed by:	dfr
  Tested by:	pho
  MFC after:	1 month

Modified:
  head/sys/kern/kern_lockf.c

Modified: head/sys/kern/kern_lockf.c
==============================================================================
--- head/sys/kern/kern_lockf.c	Sun May 24 12:32:03 2009	(r192682)
+++ head/sys/kern/kern_lockf.c	Sun May 24 12:33:16 2009	(r192683)
@@ -633,7 +633,20 @@ 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) {
+		VI_UNLOCK(vp);
+		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 +768,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 +805,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?200905241233.n4OCXGkd089814>