* 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) wh
| 2149 | * for blkno and dblkno. |
| 2150 | */ |
| 2151 | int |
| 2152 | breadn_flags(struct vnode *vp, daddr_t blkno, daddr_t dblkno, int size, |
| 2153 | daddr_t *rablkno, int *rabsize, int cnt, struct ucred *cred, int flags, |
| 2154 | void (*ckhashfunc)(struct buf *), struct buf **bpp) |
| 2155 | { |
| 2156 | struct buf *bp; |
| 2157 | struct thread *td; |
| 2158 | int error, readwait, rv; |
| 2159 | |
| 2160 | CTR3(KTR_BUF, "breadn(%p, %jd, %d)", vp, blkno, size); |
| 2161 | td = curthread; |
| 2162 | /* |
| 2163 | * Can only return NULL if GB_LOCK_NOWAIT or GB_SPARSE flags |
| 2164 | * are specified. |
| 2165 | */ |
| 2166 | error = getblkx(vp, blkno, dblkno, size, 0, 0, flags, &bp); |
| 2167 | if (error != 0) { |
| 2168 | *bpp = NULL; |
| 2169 | return (error); |
| 2170 | } |
| 2171 | KASSERT(blkno == bp->b_lblkno, |
| 2172 | ("getblkx returned buffer for blkno %jd instead of blkno %jd", |
| 2173 | (intmax_t)bp->b_lblkno, (intmax_t)blkno)); |
| 2174 | flags &= ~GB_NOSPARSE; |
| 2175 | *bpp = bp; |
| 2176 | |
| 2177 | /* |
| 2178 | * If not found in cache, do some I/O |
| 2179 | */ |
| 2180 | readwait = 0; |
| 2181 | if ((bp->b_flags & B_CACHE) == 0) { |
| 2182 | #ifdef RACCT |
| 2183 | if (racct_enable) { |
| 2184 | PROC_LOCK(td->td_proc); |
| 2185 | racct_add_buf(td->td_proc, bp, 0); |
| 2186 | PROC_UNLOCK(td->td_proc); |
| 2187 | } |
| 2188 | #endif /* RACCT */ |
| 2189 | td->td_ru.ru_inblock++; |
| 2190 | bp->b_iocmd = BIO_READ; |
| 2191 | bp->b_flags &= ~B_INVAL; |
| 2192 | if ((flags & GB_CKHASH) != 0) { |
| 2193 | bp->b_flags |= B_CKHASH; |
| 2194 | bp->b_ckhashcalc = ckhashfunc; |
| 2195 | } |
| 2196 | if ((flags & GB_CVTENXIO) != 0) |
| 2197 | bp->b_xflags |= BX_CVTENXIO; |
| 2198 | bp->b_ioflags &= ~BIO_ERROR; |
| 2199 | if (bp->b_rcred == NOCRED && cred != NOCRED) |
| 2200 | bp->b_rcred = crhold(cred); |
| 2201 | vfs_busy_pages(bp, 0); |
| 2202 | bp->b_iooffset = dbtob(bp->b_blkno); |
| 2203 | bstrategy(bp); |
| 2204 | ++readwait; |
| 2205 | } |
| 2206 | |
| 2207 | /* |
| 2208 | * Attempt to initiate asynchronous I/O on read-ahead blocks. |
nothing calls this directly
no test coverage detected