FreeBSD/sys/kern/vfs_bio.c
/*
 * Entry point for bread() and breadn() via #defines in sys/buf.h.
 *
 * Get a buffer with the specified data.  Look in the cache first.  We
 * must clear BIO_ERROR and B_INVAL prior to initiating I/O.  If B_CACHE
 * is set, the buffer is valid and we do not have to do anything, see
 * getblk(). Also starts asynchronous I/O on read-ahead blocks.
 *
 * Always return a NULL buffer pointer (in bpp) when returning an error.
 */
Entry point for bread() and breadn() via #defines in sys/buf.h.
Get a buffer with the specified data.  Look in the cache first.  We
must clear BIO_ERROR and B_INVAL prior to initiating I/O.  If B_CACHE
is set, the buffer is valid and we do not have to do anything, see
getblk(). Also starts asynchronous I/O on read-ahead blocks.

Always return a NULL buffer pointer (in bpp) when returning an error.
Entry point for bread () and breadn () via #defines in sys / buf . h . Get a buffer with the specified data . Look in the cache first . We must clear BIO_ERROR and B_INVAL prior to initiating I / O . If B_CACHE is set the buffer is valid and we do not have to do anything see getblk () . Also starts asynchronous I / O on read - ahead blocks . Always return a NULL buffer pointer ( in bpp ) when returning an error .
int
breadn_flags(struct vnode *vp, daddr_t blkno, int size, daddr_t *rablkno,
    int *rabsize, int cnt, struct ucred *cred, int flags, struct buf **bpp)
{
	struct buf *bp;
	int rv = 0, readwait = 0;
	CTR3(KTR_BUF, "breadn(%p, %jd, %d)", vp, blkno, size);
	*bpp = bp = getblk(vp, blkno, size, 0, 0, flags);
	if (bp == NULL)
		return (EBUSY);
	if ((bp->b_flags & B_CACHE) == 0) {
		if (!TD_IS_IDLETHREAD(curthread)) {
#ifdef RACCT
			if (racct_enable) {
				PROC_LOCK(curproc);
				racct_add_buf(curproc, bp, 0);
				PROC_UNLOCK(curproc);
			}
#endif 
			curthread->td_ru.ru_inblock++;
		}
		bp->b_iocmd = BIO_READ;
		bp->b_flags &= ~B_INVAL;
		bp->b_ioflags &= ~BIO_ERROR;
		if (bp->b_rcred == NOCRED && cred != NOCRED)
			bp->b_rcred = crhold(cred);
		vfs_busy_pages(bp, 0);
		bp->b_iooffset = dbtob(bp->b_blkno);
		bstrategy(bp);
		++readwait;
	}
	breada(vp, rablkno, rabsize, cnt, cred);
	if (readwait) {
		rv = bufwait(bp);
		if (rv != 0) {
			brelse(bp);
			*bpp = NULL;
		}
	}
	return (rv);
}
int breadn_flags ( struct vnode * vp , daddr_t blkno , int size , daddr_t * rablkno , int * rabsize , int cnt , struct ucred * cred , int flags , struct buf * * bpp ) { struct buf * bp ; int rv = 0 , readwait = 0 ; CTR3 ( KTR_BUF , " " , vp , blkno , size ) ; * bpp = bp = getblk ( vp , blkno , size , 0 , 0 , flags ) ; if ( bp == NULL ) return ( EBUSY ) ; if ( ( bp -> b_flags & B_CACHE ) == 0 ) { if ( ! TD_IS_IDLETHREAD ( curthread ) ) { #ifdef RACCT if ( racct_enable ) { PROC_LOCK ( curproc ) ; racct_add_buf ( curproc , bp , 0 ) ; PROC_UNLOCK ( curproc ) ; } #endif curthread -> td_ru . ru_inblock ++ ; } bp -> b_iocmd = BIO_READ ; bp -> b_flags &= ~ B_INVAL ; bp -> b_ioflags &= ~ BIO_ERROR ; if ( bp -> b_rcred == NOCRED && cred != NOCRED ) bp -> b_rcred = crhold ( cred ) ; vfs_busy_pages ( bp , 0 ) ; bp -> b_iooffset = dbtob ( bp -> b_blkno ) ; bstrategy ( bp ) ; ++ readwait ; } breada ( vp , rablkno , rabsize , cnt , cred ) ; if ( readwait ) { rv = bufwait ( bp ) ; if ( rv != 0 ) { brelse ( bp ) ; * bpp = NULL ; } } return ( rv ) ; }
Entry point for bread() and breadn() via #defines in sys/buf.h.
Entry point for bread () and breadn () via #defines in sys / buf . h .
/*
	 * Can only return NULL if GB_LOCK_NOWAIT flag is specified.
	 */ /* if not found in cache, do some I/O */ /* RACCT */