Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Aug 2009 22:13:59 +0000 (UTC)
From:      Kip Macy <kmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r196063 - in user/kmacy/releng_7_2_fcs/sys: kern sys
Message-ID:  <200908042213.n74MDxtm032179@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kmacy
Date: Tue Aug  4 22:13:58 2009
New Revision: 196063
URL: http://svn.freebsd.org/changeset/base/196063

Log:
  integrate lockf fixes from -STABLE

Modified:
  user/kmacy/releng_7_2_fcs/sys/kern/kern_lockf.c
  user/kmacy/releng_7_2_fcs/sys/sys/lockf.h

Modified: user/kmacy/releng_7_2_fcs/sys/kern/kern_lockf.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/kern/kern_lockf.c	Tue Aug  4 18:22:58 2009	(r196062)
+++ user/kmacy/releng_7_2_fcs/sys/kern/kern_lockf.c	Tue Aug  4 22:13:58 2009	(r196063)
@@ -106,7 +106,7 @@ static int	 lf_owner_matches(struct lock
     int);
 static struct lockf_entry *
 		 lf_alloc_lock(struct lock_owner *);
-static void	 lf_free_lock(struct lockf_entry *);
+static int	 lf_free_lock(struct lockf_entry *);
 static int	 lf_clearlock(struct lockf *, struct lockf_entry *);
 static int	 lf_overlaps(struct lockf_entry *, struct lockf_entry *);
 static int	 lf_blocks(struct lockf_entry *, struct lockf_entry *);
@@ -347,9 +347,13 @@ lf_alloc_lock(struct lock_owner *lo)
 	return (lf);
 }
 
-static void
+static int
 lf_free_lock(struct lockf_entry *lock)
 {
+
+	KASSERT(lock->lf_refs > 0, ("lockf_entry negative ref count %p", lock));
+	if (--lock->lf_refs > 0)
+		return (0);
 	/*
 	 * Adjust the lock_owner reference count and
 	 * reclaim the entry if this is the last lock
@@ -394,6 +398,7 @@ lf_free_lock(struct lockf_entry *lock)
 		printf("Freed lock %p\n", lock);
 #endif
 	free(lock, M_LOCKF);
+	return (1);
 }
 
 /*
@@ -540,6 +545,7 @@ lf_advlockasync(struct vop_advlockasync_
 	 * the lf_lock_owners_lock tax twice.
 	 */
 	lock = lf_alloc_lock(NULL);
+	lock->lf_refs = 1;
 	lock->lf_start = start;
 	lock->lf_end = end;
 	lock->lf_owner = lo;
@@ -633,7 +639,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 +777,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 +814,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);
 
 		/*
@@ -798,7 +822,9 @@ lf_purgelocks(struct vnode *vp, struct l
 		 * above). We don't need to bother locking since we
 		 * are the last thread using this state structure.
 		 */
-		LIST_FOREACH_SAFE(lock, &state->ls_pending, lf_link, nlock) {
+		KASSERT(LIST_EMPTY(&state->ls_pending),
+		    ("lock pending for %p", state));
+		LIST_FOREACH_SAFE(lock, &state->ls_active, lf_link, nlock) {
 			LIST_REMOVE(lock, lf_link);
 			lf_free_lock(lock);
 		}
@@ -1342,7 +1368,6 @@ static int
 lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp,
     void **cookiep)
 {
-	struct lockf_entry *block;
 	static char lockstr[] = "lockf";
 	int priority, error;
 
@@ -1362,7 +1387,7 @@ lf_setlock(struct lockf *state, struct l
 	/*
 	 * Scan lock list for this file looking for locks that would block us.
 	 */
-	while ((block = lf_getblock(state, lock))) {
+	if (lf_getblock(state, lock)) {
 		/*
 		 * Free the structure and return if nonblocking.
 		 */
@@ -1431,7 +1456,13 @@ lf_setlock(struct lockf *state, struct l
 			goto out;
 		}
 
+		lock->lf_refs++;
 		error = sx_sleep(lock, &state->ls_lock, priority, lockstr, 0);
+		if (lf_free_lock(lock)) {
+			error = EINTR;
+			goto out;
+		}
+
 		/*
 		 * We may have been awakened by a signal and/or by a
 		 * debugger continuing us (in which cases we must
@@ -1793,6 +1824,7 @@ lf_split(struct lockf *state, struct loc
 	 */
 	splitlock = lf_alloc_lock(lock1->lf_owner);
 	memcpy(splitlock, lock1, sizeof *splitlock);
+	splitlock->lf_refs = 1;
 	if (splitlock->lf_flags & F_REMOTE)
 		vref(splitlock->lf_vnode);
 
@@ -1905,9 +1937,14 @@ lf_iteratelocks_vnode(struct vnode *vp, 
 	 * make sure it doesn't go away before we are finished.
 	 */
 	STAILQ_INIT(&locks);
+	VI_LOCK(vp);
 	ls = vp->v_lockf;
-	if (!ls)
+	if (!ls) {
+		VI_UNLOCK(vp);
 		return (0);
+	}
+	ls->ls_threads++;
+	VI_UNLOCK(vp);
 
 	sx_xlock(&ls->ls_lock);
 	LIST_FOREACH(lf, &ls->ls_active, lf_link) {
@@ -1928,6 +1965,10 @@ lf_iteratelocks_vnode(struct vnode *vp, 
 		STAILQ_INSERT_TAIL(&locks, ldesc, link);
 	}
 	sx_xunlock(&ls->ls_lock);
+	VI_LOCK(vp);
+	ls->ls_threads--;
+	wakeup(ls);
+	VI_UNLOCK(vp);
 
 	/*
 	 * Call the iterator function for each lock in turn. If the

Modified: user/kmacy/releng_7_2_fcs/sys/sys/lockf.h
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/sys/lockf.h	Tue Aug  4 18:22:58 2009	(r196062)
+++ user/kmacy/releng_7_2_fcs/sys/sys/lockf.h	Tue Aug  4 22:13:58 2009	(r196063)
@@ -80,6 +80,7 @@ struct lockf_entry {
 	LIST_ENTRY(lockf_entry) lf_link;  /* (s) Linkage for lock lists */
 	struct lockf_edge_list lf_outedges; /* (s) list of out-edges */
 	struct lockf_edge_list lf_inedges; /* (s) list of out-edges */
+	int	lf_refs;	    /* (s) ref count */
 };
 LIST_HEAD(lockf_entry_list, lockf_entry);
 



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