summaryrefslogtreecommitdiff
path: root/sys/nfs/nfs_vnops.c
diff options
context:
space:
mode:
authormarius eriksen <marius@cvs.openbsd.org>2004-08-03 17:11:49 +0000
committermarius eriksen <marius@cvs.openbsd.org>2004-08-03 17:11:49 +0000
commitb8ed71e1dd36fa802eca4f3384c7c7ab410abea5 (patch)
tree36f516e146da6232ec374cbd7c288e1d9758bc6a /sys/nfs/nfs_vnops.c
parent819ed0960a343745b18452727e63b4c4dae1e1c7 (diff)
NFS commit coalescion: instead of sending a commit for each block, coalesce
these into larger ranges wherever possible. this should speed up NFS writes quite a bit. ok art@ millert@ pedro@ tedu@
Diffstat (limited to 'sys/nfs/nfs_vnops.c')
-rw-r--r--sys/nfs/nfs_vnops.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index f1a28db9e48..01ae894082b 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vnops.c,v 1.62 2004/07/21 17:30:56 marius Exp $ */
+/* $OpenBSD: nfs_vnops.c,v 1.63 2004/08/03 17:11:48 marius Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */
/*
@@ -2989,11 +2989,17 @@ nfs_writebp(bp, force)
int oldflags = bp->b_flags, retv = 1;
struct proc *p = curproc; /* XXX */
off_t off;
+ size_t cnt;
int s;
+ struct vnode *vp;
+ struct nfsnode *np;
if(!(bp->b_flags & B_BUSY))
panic("bwrite: buffer is not busy???");
+ vp = bp->b_vp;
+ np = VTONFS(vp);
+
#ifdef fvdl_debug
printf("nfs_writebp(%x): vp %x voff %d vend %d doff %d dend %d\n",
bp, bp->b_vp, bp->b_validoff, bp->b_validend, bp->b_dirtyoff,
@@ -3017,10 +3023,45 @@ nfs_writebp(bp, force)
*/
if ((oldflags & (B_NEEDCOMMIT | B_WRITEINPROG)) == B_NEEDCOMMIT) {
off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
- bp->b_flags |= B_WRITEINPROG;
- retv = nfs_commit(bp->b_vp, off, bp->b_dirtyend-bp->b_dirtyoff,
- bp->b_proc);
- bp->b_flags &= ~B_WRITEINPROG;
+ cnt = bp->b_dirtyend - bp->b_dirtyoff;
+
+ rw_enter_write(&np->n_commitlock);
+ if (!(bp->b_flags & B_NEEDCOMMIT)) {
+ rw_exit_write(&np->n_commitlock);
+ return (0);
+ }
+
+ /*
+ * If it's already been commited by somebody else,
+ * bail.
+ */
+ if (!nfs_in_committed_range(vp, bp)) {
+ int pushedrange = 0;
+ /*
+ * Since we're going to do this, push as much
+ * as we can.
+ */
+
+ if (nfs_in_tobecommitted_range(vp, bp)) {
+ pushedrange = 1;
+ off = np->n_pushlo;
+ cnt = np->n_pushhi - np->n_pushlo;
+ }
+
+ bp->b_flags |= B_WRITEINPROG;
+ retv = nfs_commit(bp->b_vp, off, cnt, bp->b_proc);
+ bp->b_flags &= ~B_WRITEINPROG;
+
+ if (retv == 0) {
+ if (pushedrange)
+ nfs_merge_commit_ranges(vp);
+ else
+ nfs_add_committed_range(vp, bp);
+ }
+ } else
+ retv = 0; /* It has already been commited. */
+
+ rw_exit_write(&np->n_commitlock);
if (!retv) {
bp->b_dirtyoff = bp->b_dirtyend = 0;
bp->b_flags &= ~B_NEEDCOMMIT;