[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

VFS write suspension diffs



Hi,

these 2 diffs add write suspension to the VFS layer of the kernel,
it's split up into 2 parts:

part1:	adds the vn_write_* functions to the VFS needed for
	the suspension.

part2:	adds the vn_write_start() vn_write_finish() calls
	around in the kernel.

This sure could use a lot of testing and reviewing to make sure
all write operations have been protected by vn_write_start() and
vn_write_finish() and if it doesn't break anything.

Thanks.

Part I:

Index: sys/kern/vfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.44
diff -u -r1.44 vfs_vnops.c
--- sys/kern/vfs_vnops.c	23 Sep 2003 16:51:12 -0000	1.44
+++ sys/kern/vfs_vnops.c	13 Jul 2004 10:59:52 -0000
@@ -342,6 +342,67 @@
 }
 
 /*
+ * Shared routines for writing to a filesystem
+ */
+int
+vn_write_start(struct mount *mp, int flags)
+{
+	if (mp == NULL)
+		return (0);
+
+	/* check filesystem suspension */
+	if (mp->mnt_flag & MNT_SUSPEND) {
+		if (flags & V_NOWAIT)
+			return (EWOULDBLOCK);
+		tsleep(&mp->mnt_flag, (PUSER - 1), "suspfs", 0);
+	}
+	
+	/* mark another write operation in progress */
+	mp->mnt_writecount++;
+
+	return (0);
+}
+
+int
+vn_write_suspend_wait(struct mount *mp, int flags)
+{
+	int error;
+
+	/* If we are not suspended yet let the operation proceed */
+	if (mp == NULL || (mp->mnt_flag & MNT_SUSPENDED) == 0)
+		return (0);
+
+	if (flags & V_NOWAIT)
+		return (EWOULDBLOCK);
+
+	/* Wait for suspension */
+	error = tsleep(&mp->mnt_flag, (PUSER - 1), "suspfs", 0);
+	return (error);
+}
+
+void
+vn_write_finish(struct mount *mp)
+{
+	if (mp == NULL)
+		return;
+
+	/* a write operation has been finished */
+	mp->mnt_writecount--;
+
+#ifdef DIAGNOSTIC
+	if (mp->mnt_writecount < 0)
+		panic("vn_write_finish: negative count for mnt_writecount");
+#endif
+
+	/* if the filesystem is trying to get suspended wake up
+	 * the process trying to obtain the suspension
+ 	 * if all write operations are finished.
+	 */
+	if ((mp->mnt_flag & MNT_SUSPEND) != 0 && mp->mnt_writecount <= 0)
+		wakeup(&mp->mnt_writecount);
+}
+
+/*
  * File table wrapper for vn_stat
  */
 int
@@ -528,4 +589,54 @@
 vn_kqfilter(struct file *fp, struct knote *kn)
 {
 	return (VOP_KQFILTER(((struct vnode *)fp->f_data), kn));
+}
+
+/*
+ * Suspend write operations on a given filesystem
+ */
+int
+vn_write_suspend(struct mount *mp)
+{
+	int error;
+	struct proc *p = curproc;
+
+	if (mp->mnt_flag & MNT_SUSPEND)
+		return (0);
+
+	/* Mark the filesystem in progress of suspension */
+	mp->mnt_flag |= MNT_SUSPEND;
+	
+	/* Wait until all write operations are done */
+	if (mp->mnt_writecount > 0)
+		tsleep(&mp->mnt_writecount, (PUSER - 1), "suspwt", 0);
+
+	/* Sync the filesystem */
+	error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p);
+	if (error) {
+		vn_write_resume(mp);
+		return (error);
+	}
+
+	/* filesystem successfully suspended */
+	mp->mnt_flag |= MNT_SUSPENDED;
+
+	return (0);
+}
+
+/*
+ * Continue write operations on a suspended filesystem
+ */
+void
+vn_write_resume(struct mount *mp)
+{
+	if ((mp->mnt_flag & MNT_SUSPEND) == 0)
+		return;
+	mp->mnt_flag &= ~MNT_SUSPENDED;
+	mp->mnt_flag &= ~MNT_SUSPEND;
+	
+	/* wake up any sleeping processes waiting for the
+	 * suspension to be removed
+	 */
+	wakeup(&mp->mnt_writecount);
+	wakeup(&mp->mnt_flag);
 }
Index: sys/sys/mount.h
===================================================================
RCS file: /cvs/src/sys/sys/mount.h,v
retrieving revision 1.58
diff -u -r1.58 mount.h
--- sys/sys/mount.h	14 Aug 2003 07:46:40 -0000	1.58
+++ sys/sys/mount.h	13 Jul 2004 10:48:21 -0000
@@ -370,6 +370,7 @@
 	struct vnodelst	mnt_vnodelist;		/* list of vnodes this mount */
 	struct lock     mnt_lock;               /* mount structure lock */
 	int		mnt_flag;		/* flags */
+	int		mnt_writecount;		/* number of write operations */
 	int		mnt_maxsymlinklen;	/* max size of short symlink */
 	struct statfs	mnt_stat;		/* cache of filesystem stats */
 	void		*mnt_data;		/* private data */
@@ -423,6 +424,9 @@
 #define	MNT_FORCE	0x00080000	/* force unmount or readonly change */
 #define MNT_WANTRDWR	0x02000000	/* want upgrade to read/write */
 #define MNT_SOFTDEP     0x04000000      /* soft dependencies being done */
+#define MNT_SUSPEND	0x10000000	/* filesystem wants to be suspended */
+#define MNT_SUSPENDED	0x20000000	/* write operations are suspended */
+
 /*
  * Sysctl CTL_VFS definitions.
  *
@@ -609,6 +613,12 @@
 #endif
 int	vfs_register(struct vfsconf *);
 int	vfs_unregister(struct vfsconf *);
+int	vn_write_start(struct mount *, int);
+void	vn_write_finish(struct mount *);
+int	vn_write_suspend(struct mount *);
+void	vn_write_resume(struct mount *);
+int	vn_write_suspend_wait(struct mount *, int);
+
 #else /* _KERNEL */
 
 #include <sys/cdefs.h>
Index: sys/sys/vnode.h
===================================================================
RCS file: /cvs/src/sys/sys/vnode.h,v
retrieving revision 1.58
diff -u -r1.58 vnode.h
--- sys/sys/vnode.h	9 Jan 2004 03:01:03 -0000	1.58
+++ sys/sys/vnode.h	13 Jul 2004 10:48:22 -0000
@@ -229,6 +229,8 @@
 
 #define REVOKEALL	0x0001		/* vop_reovke: revoke all aliases */
 
+#define	V_WAIT		0x0001		/* vn_write_start: wait for suspension */
+#define V_NOWAIT	0x0002		/* vn_write_start: don't wait */
 
 TAILQ_HEAD(freelst, vnode);
 extern struct freelst vnode_hold_list;	/* free vnodes referencing buffers */

Part II:

Index: sys/kern/tty_tty.c
===================================================================
RCS file: /cvs/src/sys/kern/tty_tty.c,v
retrieving revision 1.8
diff -u -r1.8 tty_tty.c
--- sys/kern/tty_tty.c	23 Sep 2003 16:51:12 -0000	1.8
+++ sys/kern/tty_tty.c	13 Jul 2004 19:13:52 -0000
@@ -43,7 +43,7 @@
 #include <sys/vnode.h>
 #include <sys/file.h>
 #include <sys/conf.h>
-
+#include <sys/mount.h>		/* XXX: vn_write_start / finish */
 
 #define cttyvp(p) ((p)->p_flag & P_CONTROLT ? (p)->p_session->s_ttyvp : NULL)
 
@@ -59,6 +59,10 @@
 
 	if (ttyvp == NULL)
 		return (ENXIO);
+
+	if ((error = vn_write_start(ttyvp->v_mount, V_WAIT)))
+		return (error);
+
 	vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY, p);
 #ifdef PARANOID
 	/*
@@ -75,6 +79,7 @@
 #endif /* PARANOID */
 		error = VOP_OPEN(ttyvp, flag, NOCRED, p);
 	VOP_UNLOCK(ttyvp, 0, p);
+	vn_write_finish(ttyvp->v_mount);
 	return (error);
 }
 
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.113
diff -u -r1.113 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	3 Jul 2004 18:14:02 -0000	1.113
+++ sys/kern/vfs_syscalls.c	13 Jul 2004 19:13:52 -0000
@@ -125,6 +125,7 @@
 	if ((error = namei(&nd)) != 0)
 		return (error);
 	vp = nd.ni_vp;
+
 	if (SCARG(uap, flags) & MNT_UPDATE) {
 		if ((vp->v_flag & VROOT) == 0) {
 			vput(vp);
@@ -132,6 +133,7 @@
 		}
 		mp = vp->v_mount;
 		flag = mp->mnt_flag;
+
 		/*
 		 * We only allow the filesystem to be reloaded if it
 		 * is currently mounted read-only.
@@ -426,6 +428,10 @@
 	}
 	vput(vp);
 
+	/* Don't allow suspended filesystems to be unmounted */
+	if ((mp->mnt_flag & MNT_SUSPEND) != 0)
+		return (EBUSY);
+
 	if (vfs_busy(mp, LK_EXCLUSIVE, NULL, p))
 		return (EBUSY);
 
@@ -523,13 +529,15 @@
 			nmp = CIRCLEQ_PREV(mp, mnt_list);
 			continue;
 		}
-		if ((mp->mnt_flag & MNT_RDONLY) == 0) {
+		if ((mp->mnt_flag & MNT_RDONLY) == 0 &&
+		    (vn_write_start(mp, V_NOWAIT) == 0)) {
 			asyncflag = mp->mnt_flag & MNT_ASYNC;
 			mp->mnt_flag &= ~MNT_ASYNC;
 			uvm_vnp_sync(mp);
 			VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
 			if (asyncflag)
 				mp->mnt_flag |= MNT_ASYNC;
+			vn_write_finish(mp);
 		}
 		simple_lock(&mountlist_slock);
 		nmp = CIRCLEQ_PREV(mp, mnt_list);
@@ -568,9 +576,14 @@
 	if ((error = namei(&nd)) != 0)
 		return (error);
 	mp = nd.ni_vp->v_mount;
+	error = vn_write_start(mp, V_WAIT);
 	vrele(nd.ni_vp);
-	return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
-	    SCARG(uap, arg), p));
+	if (error)
+		return (error);
+	error = VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
+	    SCARG(uap, arg), p);
+	vn_write_finish(mp);
+	return (error);
 }
 
 /*
@@ -1102,12 +1115,16 @@
 			goto bad;
 	}
 	if (flags & O_TRUNC) {
+		if ((error = vn_write_start(mp, V_WAIT)))
+			return (error);
 		VOP_UNLOCK(vp, 0, p);				/* XXX */
 		VOP_LEASE(vp, p, cred, LEASE_WRITE);
 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);	/* XXX */
 		VATTR_NULL(&va);
 		va.va_size = 0;
-		if ((error = VOP_SETATTR(vp, &va, cred, p)) != 0)
+		error = VOP_SETATTR(vp, &va, cred, p);
+		vn_write_finish(mp);
+		if (error)
 			goto bad;
 	}
 	if ((error = VOP_OPEN(vp, flags, cred, p)) != 0)
@@ -1292,6 +1309,18 @@
 			break;
 		}
 	}
+
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT))) {
+		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+		if (nd.ni_dvp == vp)
+			vrele(nd.ni_dvp);
+		else
+			vput(nd.ni_dvp);
+		if (vp)
+			vrele(vp);
+		return (error);
+	}
+
 	if (!error) {
 		VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
 		if (whiteout) {
@@ -1312,6 +1341,8 @@
 		if (vp)
 			vrele(vp);
 	}
+
+	vn_write_finish(nd.ni_dvp->v_mount);
 	return (error);
 }
 
@@ -1348,11 +1379,15 @@
 		vrele(nd.ni_vp);
 		return (EEXIST);
 	}
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		return (error);
 	VATTR_NULL(&vattr);
 	vattr.va_type = VFIFO;
 	vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
-	return (VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr));
+	error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
+	vn_write_finish(nd.ni_dvp->v_mount);
+	return (error);
 #endif /* FIFO */
 }
 
@@ -1398,9 +1433,12 @@
 		error = EEXIST;
 		goto out;
 	}
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		return (error);
 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
 	error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
+	vn_write_finish(nd.ni_dvp->v_mount);
 out:
 	vrele(vp);
 	return (error);
@@ -1442,10 +1480,14 @@
 		error = EEXIST;
 		goto out;
 	}
+
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		return (error);
 	VATTR_NULL(&vattr);
 	vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
 	error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
+	vn_write_finish(nd.ni_dvp->v_mount);
 out:
 	pool_put(&namei_pool, path);
 	return (error);
@@ -1483,11 +1525,14 @@
 			vrele(nd.ni_vp);
 		return (EEXIST);
 	}
-
+	
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		return (error);
 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
 	if ((error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) != 0)
 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 	vput(nd.ni_dvp);
+	vn_write_finish(nd.ni_dvp->v_mount);
 	return (error);
 }
 
@@ -1530,9 +1575,12 @@
 
 	(void)uvm_vnp_uncache(vp);
 
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		return (error);
 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
 	error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
+	vn_write_finish(nd.ni_dvp->v_mount);
 out:
 	return (error);
 }
@@ -1821,9 +1869,12 @@
 				goto out;
 			}
 		}
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_flags = SCARG(uap, flags);
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	vput(vp);
@@ -1868,9 +1919,12 @@
 				goto out;
 			}
 		}
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_flags = SCARG(uap, flags);
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	VOP_UNLOCK(vp, 0, p);
@@ -1909,10 +1963,14 @@
 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
 		error = EROFS;
 	else {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_mode = SCARG(uap, mode) & ALLPERMS;
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
+out:
 	vput(vp);
 	return (error);
 }
@@ -1947,10 +2005,15 @@
 	if (vp->v_mount && vp->v_mount->mnt_flag & MNT_RDONLY)
 		error = EROFS;
 	else {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_mode = SCARG(uap, mode) & ALLPERMS;
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
+
+out:
 	VOP_UNLOCK(vp, 0, p);
 	FRELE(fp);
 	return (error);
@@ -1997,11 +2060,14 @@
 		}
 		else
 			mode = VNOVAL;
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_uid = SCARG(uap, uid);
 		vattr.va_gid = SCARG(uap, gid);
 		vattr.va_mode = mode;
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	vput(vp);
@@ -2049,11 +2115,14 @@
 		}
 		else
 			mode = VNOVAL;
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_uid = SCARG(uap, uid);
 		vattr.va_gid = SCARG(uap, gid);
 		vattr.va_mode = mode;
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	vput(vp);
@@ -2099,11 +2168,14 @@
 				mode = VNOVAL;
 		} else
 			mode = VNOVAL;
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_uid = SCARG(uap, uid);
 		vattr.va_gid = SCARG(uap, gid);
 		vattr.va_mode = mode;
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	VOP_UNLOCK(vp, 0, p);
@@ -2160,8 +2232,13 @@
 		vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
 		vattr.va_mtime.tv_sec = tv[1].tv_sec;
 		vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
+
+out:
 	vput(vp);
 	return (error);
 }
@@ -2215,8 +2292,13 @@
 		vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
 		vattr.va_mtime.tv_sec = tv[1].tv_sec;
 		vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;	
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
+
+out:
 	VOP_UNLOCK(vp, 0, p);
 	FRELE(fp);
 	return (error);
@@ -2252,10 +2334,15 @@
 		error = EISDIR;
 	else if ((error = vn_writechk(vp)) == 0 &&
 	    (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		VATTR_NULL(&vattr);
 		vattr.va_size = SCARG(uap, length);
 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+		vn_write_finish(vp->v_mount);
 	}
+
+out:
 	vput(vp);
 	return (error);
 }
@@ -2292,9 +2379,14 @@
 	if (vp->v_type == VDIR)
 		error = EISDIR;
 	else if ((error = vn_writechk(vp)) == 0) {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT))) {
+			VOP_UNLOCK(vp, 0, p);
+			goto bad;
+		}
 		VATTR_NULL(&vattr);
 		vattr.va_size = SCARG(uap, length);
 		error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
+		vn_write_finish(vp->v_mount);
 	}
 	VOP_UNLOCK(vp, 0, p);
 bad:
@@ -2394,6 +2486,7 @@
 	 */
 	if (fvp == tvp)
 		error = -1;
+
 out:
 	if (!error) {
 		VOP_LEASE(tdvp, p, p->p_ucred, LEASE_WRITE);
@@ -2403,8 +2496,12 @@
 			(void)uvm_vnp_uncache(tvp);
 			VOP_LEASE(tvp, p, p->p_ucred, LEASE_WRITE);
 		}
-		error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
-				   tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
+		error = vn_write_start(tond.ni_dvp->v_mount, V_WAIT);
+		if (!error) {
+			error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, 
+			    &fromnd.ni_cnd, tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
+			vn_write_finish(tond.ni_dvp->v_mount);
+		}
 	} else {
 		VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
 		if (tdvp == tvp)
@@ -2461,6 +2558,8 @@
 		vrele(vp);
 		return (EEXIST);
 	}
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		return (error);
 	VATTR_NULL(&vattr);
 	vattr.va_type = VDIR;
 	vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask;
@@ -2468,6 +2567,7 @@
 	error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
 	if (!error)
 		vput(nd.ni_vp);
+	vn_write_finish(nd.ni_dvp->v_mount);
 	return (error);
 }
 
@@ -2509,6 +2609,10 @@
 	 */
 	if (vp->v_flag & VROOT)
 		error = EBUSY;
+	
+	if ((error = vn_write_start(nd.ni_dvp->v_mount, V_WAIT)))
+		goto out;
+
 out:
 	if (!error) {
 		VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
@@ -2522,6 +2626,8 @@
 			vput(nd.ni_dvp);
 		vput(vp);
 	}
+	
+	vn_write_finish(nd.ni_dvp->v_mount);
 	return (error);
 }
 
@@ -2783,6 +2889,7 @@
 	struct vnode *vp;
 	off_t offset;
 	int fd = SCARG(uap, fd);
+	int error;
 
 	if ((fp = fd_getfile(fdp, fd)) == NULL)
 		return (EBADF);
@@ -2790,6 +2897,10 @@
 		return (EBADF);
 
 	vp = (struct vnode *)fp->f_data;
+
+	if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+		return (error);
+
 	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
 		return (ESPIPE);
 	}
@@ -2799,8 +2910,10 @@
 	offset = SCARG(uap, offset);
 
 	/* dofilewrite() will FRELE the descriptor for us */
-	return (dofilewrite(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
-	    &offset, retval));
+	error = dofilewrite(p, fd, fp, SCARG(uap, buf), SCARG(uap, nbyte),
+	    &offset, retval);
+	vn_write_finish(vp->v_mount);
+	return (error);
 }
 
 
@@ -2825,6 +2938,7 @@
 	struct vnode *vp;
 	off_t offset;
 	int fd = SCARG(uap, fd);
+	int error;
 
 	if ((fp = fd_getfile(fdp, fd)) == NULL)
 		return (EBADF);
@@ -2832,6 +2946,10 @@
 		return (EBADF);
 
 	vp = (struct vnode *)fp->f_data;
+
+	if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+		return (error);
+
 	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
 		return (ESPIPE);
 	}
@@ -2841,8 +2959,10 @@
 	offset = SCARG(uap, offset);
 
 	/* dofilewritev() will FRELE the descriptor for us */
-	return (dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
-	    &offset, retval));
+	error = dofilewritev(p, fd, fp, SCARG(uap, iovp), SCARG(uap, iovcnt),
+	    &offset, retval);
+	vn_write_finish(vp->v_mount);
+	return (error);
 }
 
 #ifdef UFS_EXTATTR
Index: sys/kern/vfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_vnops.c,v
retrieving revision 1.44
diff -u -r1.44 vfs_vnops.c
--- sys/kern/vfs_vnops.c	23 Sep 2003 16:51:12 -0000	1.44
+++ sys/kern/vfs_vnops.c	13 Jul 2004 19:14:22 -0000
@@ -96,12 +96,15 @@
 			return (error);
 
 		if (ndp->ni_vp == NULL) {
+			if ((error = vn_write_start(ndp->ni_dvp->v_mount, V_WAIT)))
+				return (error);
 			VATTR_NULL(&va);
 			va.va_type = VREG;
 			va.va_mode = cmode;
 			VOP_LEASE(ndp->ni_dvp, p, cred, LEASE_WRITE);
 			error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
 					   &ndp->ni_cnd, &va);
+			vn_write_finish(ndp->ni_dvp->v_mount);
 			if (error)
 				return (error);
 			fmode &= ~O_TRUNC;
@@ -267,7 +270,11 @@
 	if (rw == UIO_READ) {
 		error = VOP_READ(vp, &auio, ioflg, cred);
 	} else {
-		error = VOP_WRITE(vp, &auio, ioflg, cred);
+		error = vn_write_start(vp->v_mount, V_WAIT);
+		if (!error) {	
+			error = VOP_WRITE(vp, &auio, ioflg, cred);
+			vn_write_finish(vp->v_mount);
+		}	
 	}
 	if (aresid)
 		*aresid = auio.uio_resid;
@@ -328,6 +335,8 @@
 	if ((fp->f_flag & FFSYNC) ||
 	    (vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)))
 		ioflag |= IO_SYNC;
+	if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+		return (error);
 	VOP_LEASE(vp, uio->uio_procp, cred, LEASE_WRITE);
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
 	uio->uio_offset = *poff;
@@ -338,6 +347,7 @@
 	else
 		*poff += count - uio->uio_resid;
 	VOP_UNLOCK(vp, 0, p);
+	vn_write_finish(vp->v_mount);
 	return (error);
 }
 
Index: sys/miscfs/union/union_subr.c
===================================================================
RCS file: /cvs/src/sys/miscfs/union/union_subr.c,v
retrieving revision 1.17
diff -u -r1.17 union_subr.c
--- sys/miscfs/union/union_subr.c	14 May 2004 04:00:34 -0000	1.17
+++ sys/miscfs/union/union_subr.c	13 Jul 2004 19:13:52 -0000
@@ -712,9 +712,14 @@
 	struct vnode *lvp, *uvp;
 	struct vattr lvattr, uvattr;
 
+	if ((error = vn_write_start(un->un_dirvp->v_mount, V_WAIT)))
+		return (error);
+
 	error = union_vn_create(&uvp, un, p);
-	if (error)
+	if (error) {
+		vn_write_finish(un->un_dirvp->v_mount);
 		return (error);
+	}
 
 	/* at this point, uppervp is locked */
 	union_newupper(un, uvp);
@@ -772,6 +777,7 @@
 		VOP_UNLOCK(lvp, 0, p);
 	}
 
+	vn_write_finish(un->un_dirvp->v_mount);
 	return (error);
 
 }
@@ -855,15 +861,21 @@
 	struct proc *p = cnp->cn_proc;
 	struct componentname cn;
 
+	if ((error = vn_write_start(dvp->v_mount, V_WAIT)))
+		return (error);
+
 	error = union_relookup(um, dvp, vpp, cnp, &cn,
 			cnp->cn_nameptr, cnp->cn_namelen);
-	if (error)
+	if (error) {
+		vn_write_finish(dvp->v_mount);
 		return (error);
+	}
 
 	if (*vpp) {
 		VOP_ABORTOP(dvp, &cn);
 		VOP_UNLOCK(dvp, 0, p);
 		vrele(*vpp);
+		vn_write_finish(dvp->v_mount);
 		*vpp = NULLVP;
 		return (EEXIST);
 	}
@@ -909,8 +921,13 @@
 	struct componentname cn;
 
 	VOP_UNLOCK(dvp, 0, p);
+
+	if ((error = vn_write_start(dvp->v_mount, V_WAIT)))
+		return (error);
+
 	error = union_relookup(um, dvp, &wvp, cnp, &cn, path, strlen(path));
 	if (error) {
+		vn_write_finish(dvp->v_mount);
 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
 		return (error);
 	}
@@ -919,6 +936,7 @@
 		VOP_ABORTOP(dvp, &cn);
 		vrele(dvp);
 		vrele(wvp);
+		vn_write_finish(dvp->v_mount);
 		return (EEXIST);
 	}
 
@@ -930,6 +948,7 @@
 		VOP_ABORTOP(dvp, &cn);
 
 	vrele(dvp);
+	vn_write_finish(dvp->v_mount);
 
 	return (error);
 }
Index: sys/nfs/nfs_serv.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_serv.c,v
retrieving revision 1.38
diff -u -r1.38 nfs_serv.c
--- sys/nfs/nfs_serv.c	24 Jun 2004 19:35:26 -0000	1.38
+++ sys/nfs/nfs_serv.c	13 Jul 2004 19:13:52 -0000
@@ -228,9 +228,14 @@
 	struct mbuf *mb, *mb2, *mreq;
 	u_quad_t frev;
 	struct timespec guard;
+	struct mount *mp;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	VATTR_NULL(&va);
 	if (v3) {
 		nfsm_srvsattr(&va);
@@ -279,6 +284,7 @@
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
 		nfsm_srvwcc_data(preat_ret, &preat, postat_ret, &va);
+		vn_write_finish(mp);
 		return (0);
 	}
 	if (v3) {
@@ -291,6 +297,7 @@
 			vput(vp);
 			nfsm_reply(NFSX_WCCDATA(v3));
 			nfsm_srvwcc_data(preat_ret, &preat, postat_ret, &va);
+			vn_write_finish(mp);
 			return (0);
 		}
 	}
@@ -318,6 +325,7 @@
 		error = postat_ret;
 out:
 	vput(vp);
+	vn_write_finish(mp);
 	nfsm_reply(NFSX_WCCORFATTR(v3));
 	if (v3) {
 		nfsm_srvwcc_data(preat_ret, &preat, postat_ret, &va);
@@ -704,6 +712,7 @@
 	struct uio io, *uiop = &io;
 	off_t off;
 	u_quad_t frev;
+	struct mount *mountp;
 
 	if (mrep == NULL) {
 		*mrq = NULL;
@@ -711,6 +720,10 @@
 	}
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mountp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mountp, V_WAIT)))
+		return (error);
 	if (v3) {
 		nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
 		off = fxdr_hyper(tl);
@@ -758,6 +771,7 @@
 		error = EIO;
 		nfsm_reply(2 * NFSX_UNSIGNED);
 		nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va);
+		vn_write_finish(mountp);
 		return (0);
 	}
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
@@ -765,6 +779,7 @@
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
 		nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va);
+		vn_write_finish(mountp);
 		return (0);
 	}
 	if (v3)
@@ -782,6 +797,7 @@
 		vput(vp);
 		nfsm_reply(NFSX_WCCDATA(v3));
 		nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va);
+		vn_write_finish(mountp);
 		return (0);
 	}
 
@@ -824,6 +840,7 @@
 	}
 	aftat_ret = VOP_GETATTR(vp, &va, cred, procp);
 	vput(vp);
+	vn_write_finish(mountp);
 	if (!error)
 		error = aftat_ret;
 	nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) +
@@ -886,6 +903,7 @@
 	struct uio io, *uiop = &io;
 	u_quad_t frev, cur_usec;
 	struct timeval tv;
+	struct mount *mountp;
 
 	*mrq = NULL;
 	if (*ndp) {
@@ -1079,8 +1097,16 @@
 			mp = mp->m_next;
 		    }
 		    if (!error) {
-			error = VOP_WRITE(vp, uiop, ioflags, cred);
-			nfsstats.srvvop_writes++;
+			if (vn_write_start(mountp, V_NOWAIT) != 0) {
+				VOP_UNLOCK(vp, 0, procp);
+				error =  vn_write_start(mountp, V_WAIT);
+				vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, procp);
+			}
+			if (!error) {
+				error = VOP_WRITE(vp, uiop, ioflags, cred);
+				nfsstats.srvvop_writes++;
+				vn_write_finish(mountp);
+			}
 		    }
 		    FREE((caddr_t)iov, M_TEMP);
 		}
@@ -1252,11 +1278,16 @@
 	fhandle_t *fhp;
 	u_quad_t frev, tempsize;
 	u_char cverf[NFSX_V3CREATEVERF];
+	struct mount *mp;
 
 	nd.ni_cnd.cn_nameiop = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	nfsm_srvnamesiz(len);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
 	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART;
@@ -1276,6 +1307,7 @@
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 		if (dirp)
 			vrele(dirp);
+		vn_write_finish(mp);
 		return (0);
 	}
 	VATTR_NULL(&va);
@@ -1353,6 +1385,7 @@
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 				vput(nd.ni_dvp);
 				nfsm_reply(0);
+				vn_write_finish(mp);
 				return (0);
 			} else
 				va.va_rdev = (dev_t)rdev;
@@ -1362,6 +1395,7 @@
 				vrele(nd.ni_startdir);
 				pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
 				nfsm_reply(0);
+				vn_write_finish(mp);
 				return (0);
 			}
 			nd.ni_cnd.cn_nameiop = LOOKUP;
@@ -1371,6 +1405,7 @@
 			if ((error = lookup(&nd)) != 0) {
 				pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
 				nfsm_reply(0);
+				vn_write_finish(mp);
 				return (0);
 			}
 			
@@ -1381,6 +1416,7 @@
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 				error = EINVAL;
 				nfsm_reply(0);
+				vn_write_finish(mp);
 				return (0);
 			}
 		} else {
@@ -1441,6 +1477,7 @@
 		nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR);
 		nfsm_srvfillattr(&va, fp);
 	}
+	vn_write_finish(mp);
 	return (0);
 nfsmout:
 	if (dirp)
@@ -1487,10 +1524,15 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	u_quad_t frev;
+	struct mount *mp;
 
 	nd.ni_cnd.cn_nameiop = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
@@ -1504,6 +1546,7 @@
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 		if (dirp)
 			vrele(dirp);
+		vn_write_finish(mp);
 		return (0);
 	}
 	nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
@@ -1589,6 +1632,7 @@
 		nfsm_srvpostop_attr(0, &va);
 	}
 	nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
+	vn_write_finish(mp);
 	return (0);
 nfsmout:
 	if (dirp)
@@ -1604,6 +1648,7 @@
 		vput(nd.ni_dvp);
 	if (nd.ni_vp)
 		vput(nd.ni_vp);
+	vn_write_finish(mp);
 	return (error);
 }
 
@@ -1721,12 +1766,17 @@
 	fhandle_t *ffhp, *tfhp;
 	u_quad_t frev;
 	uid_t saved_uid;
+	struct mount *mp;
 
 	ffhp = &fnfh.fh_generic;
 	tfhp = &tnfh.fh_generic;
 	fromnd.ni_cnd.cn_nameiop = 0;
 	tond.ni_cnd.cn_nameiop = 0;
 	nfsm_srvmtofh(ffhp);
+	if ((mp = vfs_getvfs(&ffhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nfsm_srvnamesiz(len);
 	/*
 	 * Remember our original uid so that we can reset cr_uid before
@@ -1753,6 +1803,7 @@
 		nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
 		if (fdirp)
 			vrele(fdirp);
+		vn_write_finish(mp);
 		return (0);
 	}
 	fvp = fromnd.ni_vp;
@@ -1850,6 +1901,7 @@
 		nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
 		nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
 	}
+	vn_write_finish(mp);
 	return (0);
 
 nfsmout:
@@ -1868,6 +1920,7 @@
 		vrele(fromnd.ni_dvp);
 		vrele(fvp);
 	}
+	vn_write_finish(mp);
 	return (error);
 }
 
@@ -1898,10 +1951,15 @@
 	nfsfh_t nfh, dnfh;
 	fhandle_t *fhp, *dfhp;
 	u_quad_t frev;
+	struct mount *mp;
 
 	fhp = &nfh.fh_generic;
 	dfhp = &dnfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nfsm_srvmtofh(dfhp);
 	nfsm_srvnamesiz(len);
 	error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
@@ -1910,6 +1968,7 @@
 		nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 		nfsm_srvpostop_attr(getret, &at);
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
+		vn_write_finish(mp);
 		return (0);
 	}
 	if (vp->v_type == VDIR && (error = suser_ucred(cred)) != 0)
@@ -1962,8 +2021,10 @@
 	if (v3) {
 		nfsm_srvpostop_attr(getret, &at);
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
+		vn_write_finish(mp);
 		return (0);
 	}
+	vn_write_finish(mp);
 	nfsm_srvdone;
 }
 
@@ -1996,10 +2057,15 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	u_quad_t frev;
+	struct mount *mp;
 
 	nd.ni_cnd.cn_nameiop = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
@@ -2088,6 +2154,7 @@
 		}
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 	}
+	vn_write_finish(mp);
 	return (0);
 nfsmout:
 	if (nd.ni_cnd.cn_nameiop) {
@@ -2105,6 +2172,7 @@
 		vrele(nd.ni_vp);
 	if (pathcp)
 		FREE(pathcp, M_TEMP);
+	vn_write_finish(mp);
 	return (error);
 }
 
@@ -2137,9 +2205,14 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	u_quad_t frev;
+	struct mount *mp;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
@@ -2160,6 +2233,7 @@
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 		if (dirp)
 			vrele(dirp);
+		vn_write_finish(mp);
 		return (0);
 	}
 	VATTR_NULL(&va);
@@ -2208,6 +2282,7 @@
 		nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR);
 		nfsm_srvfillattr(&va, fp);
 	}
+	vn_write_finish(mp);
 	return (0);
 nfsmout:
 	if (dirp)
@@ -2219,6 +2294,7 @@
 		vput(nd.ni_dvp);
 	if (nd.ni_vp)
 		vrele(nd.ni_vp);
+	vn_write_finish(mp);
 	return (error);
 }
 
@@ -2249,9 +2325,14 @@
 	fhandle_t *fhp;
 	struct nameidata nd;
 	u_quad_t frev;
+	struct mount *mp;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
+	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
+		return (ESTALE);
+	if ((error = vn_write_start(mp, V_WAIT)))
+		return (error);
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = DELETE;
@@ -2272,6 +2353,7 @@
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 		if (dirp)
 			vrele(dirp);
+		vn_write_finish(mp);
 		return (0);
 	}
 	vp = nd.ni_vp;
@@ -2309,8 +2391,10 @@
 	nfsm_reply(NFSX_WCCDATA(v3));
 	if (v3) {
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
+		vn_write_finish(mp);
 		return (0);
 	}
+	vn_write_finish(mp);
 	nfsm_srvdone;
 }
 
Index: sys/ufs/ext2fs/ext2fs_inode.c
===================================================================
RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_inode.c,v
retrieving revision 1.25
diff -u -r1.25 ext2fs_inode.c
--- sys/ufs/ext2fs/ext2fs_inode.c	24 Jun 2004 19:35:26 -0000	1.25
+++ sys/ufs/ext2fs/ext2fs_inode.c	13 Jul 2004 19:13:52 -0000
@@ -85,6 +85,8 @@
 
 	error = 0;
 	if (ip->i_e2fs_nlink == 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		if (ip->i_e2fs_size != 0) {
 			error = ext2fs_truncate(ip, (off_t)0, 0, NOCRED);
 		}
@@ -92,9 +94,13 @@
 		ip->i_e2fs_dtime = ts.tv_sec;
 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
 		ext2fs_inode_free(ip, ip->i_number, ip->i_e2fs_mode);
+		vn_write_finish(vp->v_mount);
 	}
 	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		ext2fs_update(ip, NULL, NULL, 0);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	VOP_UNLOCK(vp, 0, p);
Index: sys/ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /cvs/src/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.51
diff -u -r1.51 ffs_softdep.c
--- sys/ufs/ffs/ffs_softdep.c	24 Jun 2004 19:35:26 -0000	1.51
+++ sys/ufs/ffs/ffs_softdep.c	13 Jul 2004 19:13:52 -0000
@@ -764,11 +764,9 @@
 	case D_DIRREM:
 		/* removal of a directory entry */
 		mp = WK_DIRREM(wk)->dm_mnt;
-#if 0
-		if (vn_write_suspend_wait(NULL, mp, V_NOWAIT))
+		if (vn_write_suspend_wait(mp, V_NOWAIT))
 			panic("%s: dirrem on suspended filesystem",
 				"process_worklist_item");
-#endif
 		if (mp == matchmnt)
 			matchcnt += 1;
 		handle_workitem_remove(WK_DIRREM(wk));
@@ -777,11 +775,9 @@
 	case D_FREEBLKS:
 		/* releasing blocks and/or fragments from a file */
 		mp = WK_FREEBLKS(wk)->fb_mnt;
-#if 0
-		if (vn_write_suspend_wait(NULL, mp, V_NOWAIT))
+		if (vn_write_suspend_wait(mp, V_NOWAIT))
 			panic("%s: freeblks on suspended filesystem",
 				"process_worklist_item");
-#endif
 		if (mp == matchmnt)
 			matchcnt += 1;
 		handle_workitem_freeblocks(WK_FREEBLKS(wk));
@@ -790,11 +786,9 @@
 	case D_FREEFRAG:
 		/* releasing a fragment when replaced as a file grows */
 		mp = WK_FREEFRAG(wk)->ff_mnt;
-#if 0
-		if (vn_write_suspend_wait(NULL, mp, V_NOWAIT))
+		if (vn_write_suspend_wait(mp, V_NOWAIT))
 			panic("%s: freefrag on suspended filesystem",
 				"process_worklist_item");
-#endif
 		if (mp == matchmnt)
 			matchcnt += 1;
 		handle_workitem_freefrag(WK_FREEFRAG(wk));
@@ -803,11 +797,9 @@
 	case D_FREEFILE:
 		/* releasing an inode when its link count drops to 0 */
 		mp = WK_FREEFILE(wk)->fx_mnt;
-#if 0
-		if (vn_write_suspend_wait(NULL, mp, V_NOWAIT))
+		if (vn_write_suspend_wait(mp, V_NOWAIT))
 			panic("%s: freefile on suspended filesystem",
 				"process_worklist_item");
-#endif
 		if (mp == matchmnt)
 			matchcnt += 1;
 		handle_workitem_freefile(WK_FREEFILE(wk));
@@ -4970,24 +4962,18 @@
 			mp = pagedep->pd_mnt;
 			ino = pagedep->pd_ino;
 			FREE_LOCK(&lk);
-#if 0
-			if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
+			if (vn_write_start(mp, V_NOWAIT) != 0)
 				continue;
-#endif
 			if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
 				softdep_error("clear_remove: vget", error);
-#if 0
-				vn_finished_write(mp);
-#endif
+				vn_write_finish(mp);
 				return;
 			}
 			if ((error = VOP_FSYNC(vp, p->p_ucred, MNT_NOWAIT, p)))
 				softdep_error("clear_remove: fsync", error);
 			drain_output(vp, 0);
 			vput(vp);
-#if 0
-			vn_finished_write(mp);
-#endif
+			vn_write_finish(mp);
 			return;
 		}
 	}
@@ -5051,15 +5037,11 @@
 		if (inodedep_lookup(fs, ino, 0, &inodedep) == 0)
 			continue;
 		FREE_LOCK(&lk);
-#if 0
-		if (vn_start_write(NULL, &mp, V_NOWAIT) != 0)
+		if (vn_write_start(mp, V_NOWAIT) != 0)
 			continue;
-#endif
 		if ((error = VFS_VGET(mp, ino, &vp)) != 0) {
 			softdep_error("clear_inodedeps: vget", error);
-#if 0
-			vn_finished_write(mp);
-#endif
+			vn_write_finish(mp);
 			return;
 		}
 		if (ino == lastino) {
@@ -5071,9 +5053,7 @@
 			drain_output(vp, 0);
 		}
 		vput(vp);
-#if 0
-		vn_finished_write(mp);
-#endif
+		vn_write_finish(mp);
 		ACQUIRE_LOCK(&lk);
 		drain_output(vp, 1);
 	}
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.66
diff -u -r1.66 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c	21 Jun 2004 23:50:38 -0000	1.66
+++ sys/ufs/ffs/ffs_vfsops.c	13 Jul 2004 19:13:52 -0000
@@ -208,6 +208,8 @@
 		ronly = fs->fs_ronly;
 
 		if (ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
+			if ((error = vn_write_start(mp, V_WAIT)))
+				return (error);
 			flags = WRITECLOSE;
 			if (mp->mnt_flag & MNT_FORCE)
 				flags |= FORCECLOSE;
@@ -216,6 +218,7 @@
 				mp->mnt_flag &= ~MNT_SOFTDEP;
 			} else
 				error = ffs_flushfiles(mp, flags, p);
+			vn_write_finish(mp);
 			ronly = 1;
 		}
 
@@ -243,10 +246,13 @@
 		if (!(fs->fs_flags & FS_DOSOFTDEP) &&
 		    (mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) {
 #if 0
+			if ((error = vn_write_start(mp, V_WAIT)))
+				return (error);
 			flags = WRITECLOSE;
 			if (mp->mnt_flag & MNT_FORCE)
 				flags |= FORCECLOSE;
 			error = ffs_flushfiles(mp, flags, p);
+			vn_write_finish(mp);
 #else
 			mp->mnt_flag &= ~MNT_SOFTDEP;
 #endif
Index: sys/ufs/ufs/ufs_inode.c
===================================================================
RCS file: /cvs/src/sys/ufs/ufs/ufs_inode.c,v
retrieving revision 1.21
diff -u -r1.21 ufs_inode.c
--- sys/ufs/ufs/ufs_inode.c	20 Jan 2004 03:44:06 -0000	1.21
+++ sys/ufs/ufs/ufs_inode.c	13 Jul 2004 19:13:52 -0000
@@ -99,6 +99,8 @@
 	if (ip->i_ffs_mode == 0)
 		goto out;
 	if (ip->i_ffs_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		if (getinoquota(ip) == 0)
 			(void)ufs_quota_free_inode(ip, NOCRED);
 
@@ -108,9 +110,13 @@
 		ip->i_ffs_mode = 0;
 		ip->i_flag |= IN_CHANGE | IN_UPDATE;
 		UFS_INODE_FREE(ip, ip->i_number, mode);
+		vn_write_finish(vp->v_mount);
 	}
 	if (ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) {
+		if ((error = vn_write_start(vp->v_mount, V_WAIT)))
+			goto out;
 		UFS_UPDATE(ip, 0);
+		vn_write_finish(vp->v_mount);
 	}
 out:
 	VOP_UNLOCK(vp, 0, p);
Index: sys/ufs/ufs/ufs_quota.c
===================================================================
RCS file: /cvs/src/sys/ufs/ufs/ufs_quota.c,v
retrieving revision 1.17
diff -u -r1.17 ufs_quota.c
--- sys/ufs/ufs/ufs_quota.c	21 Jun 2004 23:50:38 -0000	1.17
+++ sys/ufs/ufs/ufs_quota.c	13 Jul 2004 19:13:52 -0000
@@ -989,6 +989,9 @@
 	if ((dqvp = dq->dq_vp) == NULLVP)
 		panic("dqsync: file");
 
+	if ((error = vn_write_start(dqvp->v_mount, V_WAIT)))
+		return (error);
+
 	if (vp != dqvp)
 		vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY, p);
 	while (dq->dq_flags & DQ_LOCK) {
@@ -997,6 +1000,7 @@
 		if ((dq->dq_flags & DQ_MOD) == 0) {
 			if (vp != dqvp)
 				VOP_UNLOCK(dqvp, 0, p);
+			vn_write_finish(dqvp->v_mount);
 			return (0);
 		}
 	}
@@ -1018,6 +1022,7 @@
 	dq->dq_flags &= ~(DQ_MOD|DQ_LOCK|DQ_WANT);
 	if (vp != dqvp)
 		VOP_UNLOCK(dqvp, 0, p);
+	vn_write_finish(dqvp->v_mount);
 	return (error);
 }
 
-- 
\\ Joris



Visit your host, monkey.org