diff options
author | marius eriksen <marius@cvs.openbsd.org> | 2004-08-03 17:11:49 +0000 |
---|---|---|
committer | marius eriksen <marius@cvs.openbsd.org> | 2004-08-03 17:11:49 +0000 |
commit | b8ed71e1dd36fa802eca4f3384c7c7ab410abea5 (patch) | |
tree | 36f516e146da6232ec374cbd7c288e1d9758bc6a /sys/nfs/nfs_vnops.c | |
parent | 819ed0960a343745b18452727e63b4c4dae1e1c7 (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.c | 51 |
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; |