FreeBSD/sys/kern/vfs_bio.c
/*
 *	vfs_bio_awrite:
 *
 *	Implement clustered async writes for clearing out B_DELWRI buffers.
 *	This is much better then the old way of writing only one buffer at
 *	a time.  Note that we may not be presented with the buffers in the 
 *	correct order, so we search for the cluster in both directions.
 */
Implement clustered async writes for clearing out B_DELWRI buffers.
This is much better then the old way of writing only one buffer at
a time.  Note that we may not be presented with the buffers in the
correct order, so we search for the cluster in both directions.
Implement clustered async writes for clearing out B_DELWRI buffers . This is much better then the old way of writing only one buffer at a time . Note that we may not be presented with the buffers in the correct order so we search for the cluster in both directions .
int
vfs_bio_awrite(struct buf *bp)
{
	struct bufobj *bo;
	int i;
	int j;
	daddr_t lblkno = bp->b_lblkno;
	struct vnode *vp = bp->b_vp;
	int ncl;
	int nwritten;
	int size;
	int maxcl;
	int gbflags;
	bo = &vp->v_bufobj;
	gbflags = (bp->b_data == unmapped_buf) ? GB_UNMAPPED : 0;
	if ((vp->v_type == VREG) && 
	    (vp->v_mount != 0) && 
	    (bp->b_flags & (B_CLUSTEROK | B_INVAL)) == B_CLUSTEROK) {
		size = vp->v_mount->mnt_stat.f_iosize;
		maxcl = MAXPHYS / size;
		BO_RLOCK(bo);
		for (i = 1; i < maxcl; i++)
			if (vfs_bio_clcheck(vp, size, lblkno + i,
			    bp->b_blkno + ((i * size) >> DEV_BSHIFT)) == 0)
				break;
		for (j = 1; i + j <= maxcl && j <= lblkno; j++) 
			if (vfs_bio_clcheck(vp, size, lblkno - j,
			    bp->b_blkno - ((j * size) >> DEV_BSHIFT)) == 0)
				break;
		BO_RUNLOCK(bo);
		--j;
		ncl = i + j;
		if (ncl != 1) {
			BUF_UNLOCK(bp);
			nwritten = cluster_wbuild(vp, size, lblkno - j, ncl,
			    gbflags);
			return (nwritten);
		}
	}
	bremfree(bp);
	bp->b_flags |= B_ASYNC;
	nwritten = bp->b_bufsize;
	(void) bwrite(bp);
	return (nwritten);
}
int vfs_bio_awrite ( struct buf * bp ) { struct bufobj * bo ; int i ; int j ; daddr_t lblkno = bp -> b_lblkno ; struct vnode * vp = bp -> b_vp ; int ncl ; int nwritten ; int size ; int maxcl ; int gbflags ; bo = & vp -> v_bufobj ; gbflags = ( bp -> b_data == unmapped_buf ) ? GB_UNMAPPED : 0 ; if ( ( vp -> v_type == VREG ) && ( vp -> v_mount != 0 ) && ( bp -> b_flags & ( B_CLUSTEROK | B_INVAL ) ) == B_CLUSTEROK ) { size = vp -> v_mount -> mnt_stat . f_iosize ; maxcl = MAXPHYS / size ; BO_RLOCK ( bo ) ; for ( i = 1 ; i < maxcl ; i ++ ) if ( vfs_bio_clcheck ( vp , size , lblkno + i , bp -> b_blkno + ( ( i * size ) >> DEV_BSHIFT ) ) == 0 ) break ; for ( j = 1 ; i + j <= maxcl && j <= lblkno ; j ++ ) if ( vfs_bio_clcheck ( vp , size , lblkno - j , bp -> b_blkno - ( ( j * size ) >> DEV_BSHIFT ) ) == 0 ) break ; BO_RUNLOCK ( bo ) ; -- j ; ncl = i + j ; if ( ncl != 1 ) { BUF_UNLOCK ( bp ) ; nwritten = cluster_wbuild ( vp , size , lblkno - j , ncl , gbflags ) ; return ( nwritten ) ; } } bremfree ( bp ) ; bp -> b_flags |= B_ASYNC ; nwritten = bp -> b_bufsize ; ( void ) bwrite ( bp ) ; return ( nwritten ) ; }
vfs_bio_awrite:
      Implement clustered async writes for clearing out B_DELWRI buffers.
vfs_bio_awrite : Implement clustered async writes for clearing out B_DELWRI buffers .
/*
	 * right now we support clustered writing only to regular files.  If
	 * we find a clusterable block we could be in the middle of a cluster
	 * rather then at the beginning.
	 */ /* Only on nodes that have the size info */ /*
		 * this is a possible cluster write
		 */ /*
	 * default (old) behavior, writing out only one block
	 *
	 * XXX returns b_bufsize instead of b_bcount for nwritten?
	 */