Subject: Re: mp->mnt_vnodelist change
To: Thor Lancelot Simon <tls@rek.tjls.com>
From: Reinoud Zandijk <reinoud@netbsd.org>
List: tech-kern
Date: 10/20/2006 01:02:24
--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Dear folks,

attached you'll find a clean patch on -current that implements the change 
of the LIST_* structures to TAILQ_* structures for mp->vnodelist and for 
syncfs.

In the process i've also stumbled on quite dirty code that could easily be 
rewritten. Some functions were converted to use LIST_ macros but others 
were just accessing the pointers themselves... I also stumbled on a LFS 
hack from the Berkly age to get LFS faster; this ancient speedup hack is 
also undone as its not nessisary anymore. Lastly, i've replaced genfs's 
explicit messing with syncfs's structures by a call to syncfs itself.

Note that the patch had to add one `int' field to struct vnode to keep the 
syncfs slot in for TAILQ_REMOVE().

One userland program is affected, usr.sbin/pstat. AFAIK it should not break 
any binary compatibilities but and old `pstat -v' will now give `vnode size 
mismatch'.

As for performance, i've tested it on FFS and with a `cvs update -dP' I 
couldn't find significantly differences in execution time. LFS *ought* to 
be slightly lighter/faster on CPU time since it doens't have to seek the 
end of the vnode list every time the vnodes are written out.

As for optical media, the story is different! :) On tests using my 
relatively fast DVD+RW, i had a worst case performance gain of 600% and on 
my CD-MRW I estimate the double of that even or more.

As for stability, i've been running and stress testing it quite harsh and 
have found no corruption or other malfunctions running a 
DEBUG+DIAGNOSTIC+LOCKDEBUG kernel.

If noone objects i'd like to commit this patch.

With regards,
Reinoud


--opJtzjQTFsWo+cga
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=DIFFS_clean

Index: sys/coda/coda_subr.c
===================================================================
RCS file: /cvsroot/src/sys/coda/coda_subr.c,v
retrieving revision 1.20
diff -u -r1.20 coda_subr.c
--- sys/coda/coda_subr.c	12 Oct 2006 01:30:47 -0000	1.20
+++ sys/coda/coda_subr.c	19 Oct 2006 20:57:12 -0000
@@ -312,10 +312,10 @@
 	struct cnode *cp;
 	int count = 0, bad = 0;
 loop:
-	for (vp = mp->mnt_vnodelist.lh_first; vp; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = nvp) {
 		if (vp->v_mount != mp)
 			goto loop;
-		nvp = vp->v_mntvnodes.le_next;
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		cp = VTOC(vp);
 		count++;
 		if (!(cp->c_flags & C_UNMOUNTING)) {
Index: sys/fs/msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.36
diff -u -r1.36 msdosfs_vfsops.c
--- sys/fs/msdosfs/msdosfs_vfsops.c	12 Oct 2006 01:32:11 -0000	1.36
+++ sys/fs/msdosfs/msdosfs_vfsops.c	19 Oct 2006 20:57:12 -0000
@@ -904,7 +904,7 @@
 	 */
 	simple_lock(&mntvnode_slock);
 loop:
-	for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
 		/*
 		 * If the vnode that we are about to sync is no longer
 		 * assoicated with this mount point, start over.
@@ -912,7 +912,7 @@
 		if (vp->v_mount != mp)
 			goto loop;
 		simple_lock(&vp->v_interlock);
-		nvp = vp->v_mntvnodes.le_next;
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		dep = VTODE(vp);
 		if (waitfor == MNT_LAZY || vp->v_type == VNON ||
 		    (((dep->de_flag &
Index: sys/fs/smbfs/smbfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/smbfs/smbfs_vfsops.c,v
retrieving revision 1.55
diff -u -r1.55 smbfs_vfsops.c
--- sys/fs/smbfs/smbfs_vfsops.c	12 Oct 2006 01:32:14 -0000	1.55
+++ sys/fs/smbfs/smbfs_vfsops.c	19 Oct 2006 20:57:12 -0000
@@ -434,7 +434,7 @@
 	 */
 	simple_lock(&mntvnode_slock);
 loop:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
 		/*
 		 * If the vnode that we are about to sync is no longer
 		 * associated with this mount point, start over.
@@ -442,7 +442,7 @@
 		if (vp->v_mount != mp)
 			goto loop;
 		simple_lock(&vp->v_interlock);
-		nvp = LIST_NEXT(vp, v_mntvnodes);
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		np = VTOSMB(vp);
 		if ((vp->v_type == VNON || (np->n_flag & NMODIFIED) == 0) &&
 		    LIST_EMPTY(&vp->v_dirtyblkhd) &&
Index: sys/fs/udf/udf_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/udf/udf_vfsops.c,v
retrieving revision 1.16
diff -u -r1.16 udf_vfsops.c
--- sys/fs/udf/udf_vfsops.c	12 Oct 2006 01:32:14 -0000	1.16
+++ sys/fs/udf/udf_vfsops.c	19 Oct 2006 20:57:12 -0000
@@ -382,7 +382,7 @@
 	struct vnode *vp;
 
 	printf("On unmount, i found the following nodes:\n");
-	LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+	TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
 		vprint("", vp);
 		if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) {
 			printf("  is locked\n");
Index: sys/fs/union/union_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/fs/union/union_vfsops.c,v
retrieving revision 1.38
diff -u -r1.38 union_vfsops.c
--- sys/fs/union/union_vfsops.c	12 Oct 2006 01:32:14 -0000	1.38
+++ sys/fs/union/union_vfsops.c	19 Oct 2006 20:57:12 -0000
@@ -350,9 +350,9 @@
 		int n;
 
 		/* count #vnodes held on mount list */
-		for (n = 0, vp = mp->mnt_vnodelist.lh_first;
+		for (n = 0, vp = TAILQ_FIRST(&mp->mnt_vnodelist);
 				vp != NULLVP;
-				vp = vp->v_mntvnodes.le_next)
+				vp = TAILQ_NEXT(vp, v_mntvnodes))
 			n++;
 
 		/* if this is unchanged then stop */
Index: sys/kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.271
diff -u -r1.271 vfs_subr.c
--- sys/kern/vfs_subr.c	12 Oct 2006 01:32:19 -0000	1.271
+++ sys/kern/vfs_subr.c	19 Oct 2006 20:57:13 -0000
@@ -361,7 +361,7 @@
 	lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
 	simple_lock_init(&mp->mnt_slock);
 	(void)vfs_busy(mp, LK_NOWAIT, 0);
-	LIST_INIT(&mp->mnt_vnodelist);
+	TAILQ_INIT(&mp->mnt_vnodelist);
 	mp->mnt_op = vfsp;
 	mp->mnt_flag = MNT_RDONLY;
 	mp->mnt_vnodecovered = NULLVP;
@@ -652,12 +652,17 @@
 	 * Delete from old mount point vnode list, if on one.
 	 */
 	if (vp->v_mount != NULL)
-		LIST_REMOVE(vp, v_mntvnodes);
+		TAILQ_REMOVE(&vp->v_mount->mnt_vnodelist, vp, v_mntvnodes);
 	/*
 	 * Insert into list of vnodes for the new mount point, if available.
 	 */
-	if ((vp->v_mount = mp) != NULL)
-		LIST_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
+	if ((vp->v_mount = mp) != NULL) {
+		if (TAILQ_EMPTY(&mp->mnt_vnodelist)) {
+			TAILQ_INSERT_HEAD(&mp->mnt_vnodelist, vp, v_mntvnodes);
+		} else {
+			TAILQ_INSERT_TAIL(&mp->mnt_vnodelist, vp, v_mntvnodes);
+		}
+	}
 	simple_unlock(&mntvnode_slock);
 }
 
@@ -948,8 +953,8 @@
 
 	if (TAILQ_EMPTY(&vp->v_uobj.memq) && (vp->v_flag & VONWORKLST) &&
 	    LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
-		vp->v_flag &= ~(VWRITEMAPDIRTY|VONWORKLST);
-		LIST_REMOVE(vp, v_synclist);
+		vp->v_flag &= ~VWRITEMAPDIRTY;
+		vn_syncer_remove_from_worklist(vp);
 	}
 
 	bp->b_vp = NULL;
@@ -984,8 +989,8 @@
 		if (TAILQ_EMPTY(&newvp->v_uobj.memq) &&
 		    (newvp->v_flag & VONWORKLST) &&
 		    LIST_FIRST(&newvp->v_dirtyblkhd) == NULL) {
-			newvp->v_flag &= ~(VWRITEMAPDIRTY|VONWORKLST);
-			LIST_REMOVE(newvp, v_synclist);
+			newvp->v_flag &= ~VWRITEMAPDIRTY;
+			vn_syncer_remove_from_worklist(newvp);
 		}
 	} else {
 		listheadp = &newvp->v_dirtyblkhd;
@@ -1411,10 +1416,10 @@
 
 	simple_lock(&mntvnode_slock);
 loop:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = nvp) {
 		if (vp->v_mount != mp)
 			goto loop;
-		nvp = LIST_NEXT(vp, v_mntvnodes);
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		/*
 		 * Skip over a selected vnode.
 		 */
@@ -1880,7 +1885,7 @@
 			nmp = CIRCLEQ_NEXT(mp, mnt_list);
 			continue;
 		}
-		LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+		TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
 			if (VOP_ISLOCKED(vp))
 				vprint(NULL, vp);
 		}
@@ -2023,7 +2028,7 @@
 		savebp = bp;
 again:
 		simple_lock(&mntvnode_slock);
-		for (vp = LIST_FIRST(&mp->mnt_vnodelist);
+		for (vp = TAILQ_FIRST(&mp->mnt_vnodelist);
 		     vp != NULL;
 		     vp = nvp) {
 			/*
@@ -2038,7 +2043,7 @@
 				bp = savebp;
 				goto again;
 			}
-			nvp = LIST_NEXT(vp, v_mntvnodes);
+			nvp = TAILQ_NEXT(vp, v_mntvnodes);
 			if (bp + VPTRSZ + VNODESZ > ewhere) {
 				simple_unlock(&mntvnode_slock);
 				*sizep = bp - where;
@@ -2731,7 +2736,7 @@
 		struct vnode *vp;
 		(*pr)("locked vnodes =");
 		/* XXX would take mountlist lock, except ddb may not have context */
-		LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+		TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
 			if (VOP_ISLOCKED(vp)) {
 				if ((++cnt % 6) == 0) {
 					(*pr)(" %p,\n\t", vp);
@@ -2748,8 +2753,8 @@
 		struct vnode *vp;
 		(*pr)("all vnodes =");
 		/* XXX would take mountlist lock, except ddb may not have context */
-		LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
-			if (!LIST_NEXT(vp, v_mntvnodes)) {
+		TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+			if (!TAILQ_NEXT(vp, v_mntvnodes)) {
 				(*pr)(" %p", vp);
 			} else if ((++cnt % 6) == 0) {
 				(*pr)(" %p,\n\t", vp);
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.272
diff -u -r1.272 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	17 Oct 2006 15:06:18 -0000	1.272
+++ sys/kern/vfs_syscalls.c	19 Oct 2006 20:57:13 -0000
@@ -645,7 +645,7 @@
 		vrele(coveredvp);
 	}
 	mp->mnt_op->vfs_refcount--;
-	if (LIST_FIRST(&mp->mnt_vnodelist) != NULL)
+	if (TAILQ_FIRST(&mp->mnt_vnodelist) != NULL)
 		panic("unmount: dangling vnode");
 	mp->mnt_iflag |= IMNT_GONE;
 	lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock);
Index: sys/miscfs/genfs/genfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/genfs/genfs_vnops.c,v
retrieving revision 1.136
diff -u -r1.136 genfs_vnops.c
--- sys/miscfs/genfs/genfs_vnops.c	14 Oct 2006 09:16:28 -0000	1.136
+++ sys/miscfs/genfs/genfs_vnops.c	19 Oct 2006 20:57:13 -0000
@@ -1090,10 +1090,8 @@
 		s = splbio();
 		if (vp->v_flag & VONWORKLST) {
 			vp->v_flag &= ~VWRITEMAPDIRTY;
-			if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
-				vp->v_flag &= ~VONWORKLST;
-				LIST_REMOVE(vp, v_synclist);
-			}
+			if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL)
+				vn_syncer_remove_from_worklist(vp);
 		}
 		splx(s);
 		simple_unlock(slock);
@@ -1278,7 +1276,7 @@
 		 */
 
 		if (needs_clean) {
-			KDASSERT((vp->v_flag & VONWORKLST));
+			 KDASSERT((vp->v_flag & VONWORKLST));
 			wasclean = FALSE;
 			memset(pgs, 0, sizeof(pgs));
 			pg->flags |= PG_BUSY;
@@ -1435,10 +1433,8 @@
 	if (cleanall && wasclean && gp->g_dirtygen == dirtygen &&
 	    (vp->v_flag & VONWORKLST) != 0) {
 		vp->v_flag &= ~VWRITEMAPDIRTY;
-		if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL) {
-			vp->v_flag &= ~VONWORKLST;
-			LIST_REMOVE(vp, v_synclist);
-		}
+		if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL)
+			vn_syncer_remove_from_worklist(vp);
 	}
 	splx(s);
 
Index: sys/miscfs/syncfs/sync_subr.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/syncfs/sync_subr.c,v
retrieving revision 1.24
diff -u -r1.24 sync_subr.c
--- sys/miscfs/syncfs/sync_subr.c	12 Oct 2006 01:32:27 -0000	1.24
+++ sys/miscfs/syncfs/sync_subr.c	19 Oct 2006 20:57:13 -0000
@@ -79,7 +79,7 @@
 	    M_VNODE, M_WAITOK);
 
 	for (i = 0; i < syncer_last; i++)
-		LIST_INIT(&syncer_workitem_pending[i]);
+		TAILQ_INIT(&syncer_workitem_pending[i]);
 
 	lockinit(&syncer_lock, PVFS, "synclk", 0, 0);
 }
@@ -118,19 +118,22 @@
 	struct vnode *vp;
 	int delayx;
 {
-	int s, slot;
+	struct synclist *slp;
+	int s;
 
 	s = splbio();
 
 	if (vp->v_flag & VONWORKLST) {
-		LIST_REMOVE(vp, v_synclist);
+		slp = &syncer_workitem_pending[vp->v_synclist_slot];
+		TAILQ_REMOVE(slp, vp, v_synclist);
 	}
 
 	if (delayx > syncer_maxdelay - 2)
 		delayx = syncer_maxdelay - 2;
-	slot = (syncer_delayno + delayx) % syncer_last;
+	vp->v_synclist_slot = (syncer_delayno + delayx) % syncer_last;
 
-	LIST_INSERT_HEAD(&syncer_workitem_pending[slot], vp, v_synclist);
+	slp = &syncer_workitem_pending[vp->v_synclist_slot];
+	TAILQ_INSERT_TAIL(slp, vp, v_synclist);
 	vp->v_flag |= VONWORKLST;
 	splx(s);
 }
@@ -142,13 +145,15 @@
 vn_syncer_remove_from_worklist(vp)
 	struct vnode *vp;
 {
+	struct synclist *slp;
 	int s;
 
 	s = splbio();
 
 	if (vp->v_flag & VONWORKLST) {
 		vp->v_flag &= ~VONWORKLST;
-		LIST_REMOVE(vp, v_synclist);
+		slp = &syncer_workitem_pending[vp->v_synclist_slot];
+		TAILQ_REMOVE(slp, vp, v_synclist);
 	}
 
 	splx(s);
@@ -184,7 +189,7 @@
 
 		lockmgr(&syncer_lock, LK_EXCLUSIVE, NULL);
 
-		while ((vp = LIST_FIRST(slp)) != NULL) {
+		while ((vp = TAILQ_FIRST(slp)) != NULL) {
 			if (vn_start_write(vp, &mp, V_NOWAIT) == 0) {
 				if (vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT)
 				    == 0) {
@@ -195,7 +200,7 @@
 				vn_finished_write(mp, 0);
 			}
 			s = splbio();
-			if (LIST_FIRST(slp) == vp) {
+			if (TAILQ_FIRST(slp) == vp) {
 
 				/*
 				 * Put us back on the worklist.  The worklist
Index: sys/miscfs/syncfs/syncfs.h
===================================================================
RCS file: /cvsroot/src/sys/miscfs/syncfs/syncfs.h,v
retrieving revision 1.9
diff -u -r1.9 syncfs.h
--- sys/miscfs/syncfs/syncfs.h	11 Dec 2005 12:24:51 -0000	1.9
+++ sys/miscfs/syncfs/syncfs.h	19 Oct 2006 20:57:13 -0000
@@ -58,6 +58,6 @@
 
 extern int syncer_maxdelay;	/* maximum delay time */
 extern struct lock syncer_lock;	/* lock to freeze syncer during unmount */
-LIST_HEAD(synclist, vnode);
+TAILQ_HEAD(synclist, vnode);
 
 #endif /* _MISCFS_SYNCFS_SYNCFS_H_ */
Index: sys/nfs/nfs_subs.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_subs.c,v
retrieving revision 1.175
diff -u -r1.175 nfs_subs.c
--- sys/nfs/nfs_subs.c	17 Oct 2006 18:21:29 -0000	1.175
+++ sys/nfs/nfs_subs.c	19 Oct 2006 20:57:14 -0000
@@ -2700,7 +2700,7 @@
 
 	lockmgr(&nmp->nm_writeverflock, LK_EXCLUSIVE, NULL);
 
-	LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+	TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
 		KASSERT(vp->v_mount == mp);
 		if (vp->v_type != VREG)
 			continue;
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.165
diff -u -r1.165 nfs_vfsops.c
--- sys/nfs/nfs_vfsops.c	12 Oct 2006 01:32:47 -0000	1.165
+++ sys/nfs/nfs_vfsops.c	19 Oct 2006 20:57:14 -0000
@@ -966,7 +966,7 @@
 	 * Force stale buffer cache information to be flushed.
 	 */
 loop:
-	LIST_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
+	TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_mntvnodes) {
 		/*
 		 * If the vnode that we are about to sync is no longer
 		 * associated with this mount point, start over.
Index: sys/sys/mount.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mount.h,v
retrieving revision 1.148
diff -u -r1.148 mount.h
--- sys/sys/mount.h	4 Aug 2006 16:29:51 -0000	1.148
+++ sys/sys/mount.h	19 Oct 2006 20:57:14 -0000
@@ -89,7 +89,7 @@
  * array of operations and an instance record.  The file systems are
  * put on a doubly linked list.
  */
-LIST_HEAD(vnodelst, vnode);
+TAILQ_HEAD(vnodelst, vnode);
 
 struct mount {
 	CIRCLEQ_ENTRY(mount) mnt_list;		/* mount list */
Index: sys/sys/vnode.h
===================================================================
RCS file: /cvsroot/src/sys/sys/vnode.h,v
retrieving revision 1.157
diff -u -r1.157 vnode.h
--- sys/sys/vnode.h	17 Oct 2006 14:51:51 -0000	1.157
+++ sys/sys/vnode.h	19 Oct 2006 20:57:14 -0000
@@ -105,10 +105,11 @@
 	struct mount	*v_mount;		/* ptr to vfs we are in */
 	int		(**v_op)(void *);	/* vnode operations vector */
 	TAILQ_ENTRY(vnode) v_freelist;		/* vnode freelist */
-	LIST_ENTRY(vnode) v_mntvnodes;		/* vnodes for mount point */
+	TAILQ_ENTRY(vnode) v_mntvnodes;		/* vnodes for mount point */
 	struct buflists	v_cleanblkhd;		/* clean blocklist head */
 	struct buflists	v_dirtyblkhd;		/* dirty blocklist head */
-	LIST_ENTRY(vnode) v_synclist;		/* vnodes with dirty buffers */
+	int		v_synclist_slot;	/* synclist slot index */
+	TAILQ_ENTRY(vnode) v_synclist;		/* vnodes with dirty buffers */
 	LIST_HEAD(, namecache) v_dnclist;	/* namecaches for children */
 	LIST_HEAD(, namecache) v_nclist;	/* namecaches for our parent */
 	union {
Index: sys/ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.102
diff -u -r1.102 ext2fs_vfsops.c
--- sys/ufs/ext2fs/ext2fs_vfsops.c	12 Oct 2006 01:32:51 -0000	1.102
+++ sys/ufs/ext2fs/ext2fs_vfsops.c	19 Oct 2006 20:57:14 -0000
@@ -541,12 +541,12 @@
 
 loop:
 	simple_lock(&mntvnode_slock);
-	for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mountp->mnt_vnodelist); vp != NULL; vp = nvp) {
 		if (vp->v_mount != mountp) {
 			simple_unlock(&mntvnode_slock);
 			goto loop;
 		}
-		nvp = vp->v_mntvnodes.le_next;
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		/*
 		 * Step 4: invalidate all inactive vnodes.
 		 */
@@ -846,7 +846,7 @@
 	 */
 	simple_lock(&mntvnode_slock);
 loop:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
 		/*
 		 * If the vnode that we are about to sync is no longer
 		 * associated with this mount point, start over.
@@ -854,7 +854,7 @@
 		if (vp->v_mount != mp)
 			goto loop;
 		simple_lock(&vp->v_interlock);
-		nvp = LIST_NEXT(vp, v_mntvnodes);
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		ip = VTOI(vp);
 		if (vp->v_type == VNON ||
 		    ((ip->i_flag &
Index: sys/ufs/ffs/ffs_snapshot.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_snapshot.c,v
retrieving revision 1.33
diff -u -r1.33 ffs_snapshot.c
--- sys/ufs/ffs/ffs_snapshot.c	12 Oct 2006 01:32:51 -0000	1.33
+++ sys/ufs/ffs/ffs_snapshot.c	19 Oct 2006 20:57:14 -0000
@@ -363,14 +363,14 @@
 	    FSMAXSNAP + 1 /* superblock */ + 1 /* last block */ + 1 /* size */;
 	MNT_ILOCK(mp);
 loop:
-	for (xvp = LIST_FIRST(&mp->mnt_vnodelist); xvp; xvp = nvp) {
+	for (xvp = TAILQ_FIRST(&mp->mnt_vnodelist); xvp; xvp = nvp) {
 		/*
 		 * Make sure this vnode wasn't reclaimed in getnewvnode().
 		 * Start over if it has (it won't be on the list anymore).
 		 */
 		if (xvp->v_mount != mp)
 			goto loop;
-		nvp = LIST_NEXT(xvp, v_mntvnodes);
+		nvp = TAILQ_NEXT(xvp, v_mntvnodes);
 		VI_LOCK(xvp);
 		MNT_IUNLOCK(mp);
 		if ((xvp->v_flag & VXLOCK) ||
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.187
diff -u -r1.187 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c	12 Oct 2006 01:32:51 -0000	1.187
+++ sys/ufs/ffs/ffs_vfsops.c	19 Oct 2006 20:57:15 -0000
@@ -650,12 +650,12 @@
 
 loop:
 	simple_lock(&mntvnode_slock);
-	for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
 		if (vp->v_mount != mp) {
 			simple_unlock(&mntvnode_slock);
 			goto loop;
 		}
-		nvp = vp->v_mntvnodes.le_next;
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		/*
 		 * Step 4: invalidate all inactive vnodes.
 		 */
@@ -1314,7 +1314,7 @@
 	 */
 	simple_lock(&mntvnode_slock);
 loop:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nvp) {
 		/*
 		 * If the vnode that we are about to sync is no longer
 		 * associated with this mount point, start over.
@@ -1322,7 +1322,7 @@
 		if (vp->v_mount != mp)
 			goto loop;
 		simple_lock(&vp->v_interlock);
-		nvp = LIST_NEXT(vp, v_mntvnodes);
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 		ip = VTOI(vp);
 		if (vp->v_type == VNON ||
 		    ((ip->i_flag &
Index: sys/ufs/lfs/lfs_segment.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_segment.c,v
retrieving revision 1.193
diff -u -r1.193 lfs_segment.c
--- sys/ufs/lfs/lfs_segment.c	12 Oct 2006 01:32:51 -0000	1.193
+++ sys/ufs/lfs/lfs_segment.c	19 Oct 2006 20:57:15 -0000
@@ -494,26 +494,16 @@
 	int error = 0;
 
 	ASSERT_SEGLOCK(fs);
-#ifndef LFS_NO_BACKVP_HACK
-	/* BEGIN HACK */
-#define	VN_OFFSET	\
-	(((caddr_t)&LIST_NEXT(vp, v_mntvnodes)) - (caddr_t)vp)
-#define	BACK_VP(VP)	\
-	((struct vnode *)(((caddr_t)(VP)->v_mntvnodes.le_prev) - VN_OFFSET))
-#define	BEG_OF_VLIST	\
-	((struct vnode *)(((caddr_t)&LIST_FIRST(&mp->mnt_vnodelist)) \
-	- VN_OFFSET))
-
-	/* Find last vnode. */
- loop:	for (vp = LIST_FIRST(&mp->mnt_vnodelist);
-	     vp && LIST_NEXT(vp, v_mntvnodes) != NULL;
-	     vp = LIST_NEXT(vp, v_mntvnodes));
-	for (; vp && vp != BEG_OF_VLIST; vp = nvp) {
-		nvp = BACK_VP(vp);
+#if 0
+	/* start at last vnode. */
+	loop:
+	for (vp = TAILQ_LAST(&mp->mnt_vnodelist, vnodelst); vp; vp = nvp) {
+		nvp = TAILQ_PREV(vp, vnodelst, v_mntvnodes);
 #else
+	/* start at oldest accessed vnode */
 	loop:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp; vp = nvp) {
-		nvp = LIST_NEXT(vp, v_mntvnodes);
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp; vp = nvp) {
+		nvp = TAILQ_NEXT(vp, v_mntvnodes);
 #endif
 		/*
 		 * If the vnode that we are about to sync is no longer
Index: sys/ufs/lfs/lfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/lfs/lfs_vnops.c,v
retrieving revision 1.191
diff -u -r1.191 lfs_vnops.c
--- sys/ufs/lfs/lfs_vnops.c	12 Oct 2006 01:32:52 -0000	1.191
+++ sys/ufs/lfs/lfs_vnops.c	19 Oct 2006 20:57:15 -0000
@@ -1907,10 +1907,8 @@
 	if (vp->v_uobj.uo_npages == 0) {
 		s = splbio();
 		if (LIST_FIRST(&vp->v_dirtyblkhd) == NULL &&
-		    (vp->v_flag & VONWORKLST)) {
-			vp->v_flag &= ~VONWORKLST;
-			LIST_REMOVE(vp, v_synclist);
-		}
+		    (vp->v_flag & VONWORKLST))
+			vn_syncer_remove_from_worklist(vp);
 		splx(s);
 		simple_unlock(&vp->v_interlock);
 		
Index: sys/ufs/ufs/ufs_quota.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_quota.c,v
retrieving revision 1.41
diff -u -r1.41 ufs_quota.c
--- sys/ufs/ufs/ufs_quota.c	23 Jul 2006 22:06:15 -0000	1.41
+++ sys/ufs/ufs/ufs_quota.c	19 Oct 2006 20:57:15 -0000
@@ -384,8 +384,8 @@
 	 * NB: only need to add dquot's for inodes being modified.
 	 */
 again:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nextvp) {
-		nextvp = LIST_NEXT(vp, v_mntvnodes);
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nextvp) {
+		nextvp = TAILQ_NEXT(vp, v_mntvnodes);
 		if (vp->v_type == VNON ||vp->v_writecount == 0)
 			continue;
 		if (vget(vp, LK_EXCLUSIVE))
@@ -395,7 +395,7 @@
 			break;
 		}
 		vput(vp);
-		if (LIST_NEXT(vp, v_mntvnodes) != nextvp || vp->v_mount != mp)
+		if (TAILQ_NEXT(vp, v_mntvnodes) != nextvp || vp->v_mount != mp)
 			goto again;
 	}
 	ump->um_qflags[type] &= ~QTF_OPENING;
@@ -425,8 +425,8 @@
 	 * deleting any references to quota file being closed.
 	 */
 again:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nextvp) {
-		nextvp = LIST_NEXT(vp, v_mntvnodes);
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nextvp) {
+		nextvp = TAILQ_NEXT(vp, v_mntvnodes);
 		if (vp->v_type == VNON)
 			continue;
 		if (vget(vp, LK_EXCLUSIVE))
@@ -436,7 +436,7 @@
 		ip->i_dquot[type] = NODQUOT;
 		dqrele(vp, dq);
 		vput(vp);
-		if (LIST_NEXT(vp, v_mntvnodes) != nextvp || vp->v_mount != mp)
+		if (TAILQ_NEXT(vp, v_mntvnodes) != nextvp || vp->v_mount != mp)
 			goto again;
 	}
 	dqflush(qvp);
@@ -595,10 +595,10 @@
 	 */
 	simple_lock(&mntvnode_slock);
 again:
-	for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nextvp) {
+	for (vp = TAILQ_FIRST(&mp->mnt_vnodelist); vp != NULL; vp = nextvp) {
 		if (vp->v_mount != mp)
 			goto again;
-		nextvp = LIST_NEXT(vp, v_mntvnodes);
+		nextvp = TAILQ_NEXT(vp, v_mntvnodes);
 		if (vp->v_type == VNON)
 			continue;
 		simple_lock(&vp->v_interlock);
@@ -617,7 +617,7 @@
 		}
 		vput(vp);
 		simple_lock(&mntvnode_slock);
-		if (LIST_NEXT(vp, v_mntvnodes) != nextvp)
+		if (TAILQ_NEXT(vp, v_mntvnodes) != nextvp)
 			goto again;
 	}
 	simple_unlock(&mntvnode_slock);
Index: usr.sbin/pstat/pstat.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pstat/pstat.c,v
retrieving revision 1.95
diff -u -r1.95 pstat.c
--- usr.sbin/pstat/pstat.c	25 May 2006 01:49:30 -0000	1.95
+++ usr.sbin/pstat/pstat.c	19 Oct 2006 20:57:16 -0000
@@ -740,8 +740,8 @@
 	for (mp = mountlist.cqh_first;;
 	    mp = mount.mnt_list.cqe_next) {
 		KGET2(mp, &mount, sizeof(mount), "mount entry");
-		for (vp = mount.mnt_vnodelist.lh_first;
-		    vp != NULL; vp = vnode.v_mntvnodes.le_next) {
+		for (vp = TAILQ_FIRST(&mount.mnt_vnodelist);
+		    vp != NULL; vp = TAILQ_NEXT(&vnode, v_mntvnodes)) {
 			KGET2(vp, &vnode, sizeof(vnode), "vnode");
 			if (bp + VPTRSZ + VNODESZ > ep)
 				/* XXX - should realloc */

--opJtzjQTFsWo+cga--