freebsd-skq/sys/gnu/ext2fs
Poul-Henning Kamp e3c5a7a4dd When we traverse the vnodes on a mountpoint we need to look out for
our cached 'next vnode' being removed from this mountpoint.  If we
find that it was recycled, we restart our traversal from the start
of the list.

Code to do that is in all local disk filesystems (and a few other
places) and looks roughly like this:

		MNT_ILOCK(mp);
	loop:
		for (vp = TAILQ_FIRST(&mp...);
		    (vp = nvp) != NULL;
		    nvp = TAILQ_NEXT(vp,...)) {
			if (vp->v_mount != mp)
				goto loop;
			MNT_IUNLOCK(mp);
			...
			MNT_ILOCK(mp);
		}
		MNT_IUNLOCK(mp);

The code which takes vnodes off a mountpoint looks like this:

	MNT_ILOCK(vp->v_mount);
	...
	TAILQ_REMOVE(&vp->v_mount->mnt_nvnodelist, vp, v_nmntvnodes);
	...
	MNT_IUNLOCK(vp->v_mount);
	...
	vp->v_mount = something;

(Take a moment and try to spot the locking error before you read on.)

On a SMP system, one CPU could have removed nvp from our mountlist
but not yet gotten to assign a new value to vp->v_mount while another
CPU simultaneously get to the top of the traversal loop where it
finds that (vp->v_mount != mp) is not true despite the fact that
the vnode has indeed been removed from our mountpoint.

Fix:

Introduce the macro MNT_VNODE_FOREACH() to traverse the list of
vnodes on a mountpoint while taking into account that vnodes may
be removed from the list as we go.  This saves approx 65 lines of
duplicated code.

Split the insmntque() which potentially moves a vnode from one mount
point to another into delmntque() and insmntque() which does just
what the names say.

Fix delmntque() to set vp->v_mount to NULL while holding the
mountpoint lock.
2004-07-04 08:52:35 +00:00
..
COPYRIGHT.INFO
ext2_alloc.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_balloc.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_bitops.h Change of plans: Add ext2_bitops.h with generic and portable 2003-08-25 01:39:47 +00:00
ext2_bmap.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_extern.h Do the dreaded s/dev_t/struct cdev */ 2004-06-16 09:47:26 +00:00
ext2_fs_sb.h Enforce the file size limit in VOP_WRITE() as well as VOP_TRUNCATE(); 2004-02-19 09:06:06 +00:00
ext2_fs.h Add partial support for large (>4GB) files on ext2 filesystems. This 2004-02-18 14:08:25 +00:00
ext2_ihash.c Do the dreaded s/dev_t/struct cdev */ 2004-06-16 09:47:26 +00:00
ext2_inode_cnv.c Add partial support for large (>4GB) files on ext2 filesystems. This 2004-02-18 14:08:25 +00:00
ext2_inode.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_linux_balloc.c Fix the alpha tinderbox. The alpha specific bitops used by the bitmap 2003-10-29 07:35:53 +00:00
ext2_linux_ialloc.c Fix the alpha tinderbox. The alpha specific bitops used by the bitmap 2003-10-29 07:35:53 +00:00
ext2_lookup.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_mount.h Fixed misformatting in previous commit. 2004-06-20 03:34:21 +00:00
ext2_readwrite.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_subr.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
ext2_vfsops.c When we traverse the vnodes on a mountpoint we need to look out for 2004-07-04 08:52:35 +00:00
ext2_vnops.c Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
fs.h Remove advertising clause from University of California Regent's 2004-04-07 20:46:16 +00:00
i386-bitops.h
inode.h Fixed misformatting of code and breaking of a comment in previous commit. 2004-06-20 03:36:31 +00:00
sparc64-bitops.h