#ifndef _SYS_BUF2_H_
#define _SYS_BUF2_H_
#ifdef _KERNEL
#ifndef _SYS_BUF_H_
#include <sys/buf.h>
#endif
#ifndef _SYS_MOUNT_H_
#include <sys/mount.h>
#endif
#ifndef _SYS_VNODE_H_
#include <sys/vnode.h>
#endif
#ifndef _VM_VM_PAGE_H_
#include <vm/vm_page.h>
#endif
#define BUF_LOCKINIT(bp) \
lockinit(&(bp)->b_lock, buf_wmesg, 0, LK_NOCOLLSTATS)
static __inline int
BUF_LOCK(struct buf *bp, int locktype)
{
bp->b_lock.lk_wmesg = buf_wmesg;
return (lockmgr(&(bp)->b_lock, locktype));
}
static __inline int
BUF_TIMELOCK(struct buf *bp, int locktype, char *wmesg, int timo)
{
bp->b_lock.lk_wmesg = wmesg;
bp->b_lock.lk_timo = timo;
return (lockmgr(&(bp)->b_lock, locktype | LK_TIMELOCK));
}
static __inline void
BUF_UNLOCK(struct buf *bp)
{
lockmgr(&(bp)->b_lock, LK_RELEASE);
}
static __inline void
BUF_KERNPROC(struct buf *bp)
{
lockmgr_kernproc(&(bp)->b_lock);
}
static __inline int
BUF_LOCKINUSE(struct buf *bp)
{
return (lockinuse(&(bp)->b_lock));
}
#define BUF_LOCKFREE(bp) \
if (BUF_LOCKINUSE(bp)) \
panic("free locked buf")
static __inline void
bioq_init(struct bio_queue_head *bioq)
{
TAILQ_INIT(&bioq->queue);
bioq->off_unused = 0;
bioq->reorder = 0;
bioq->transition = NULL;
bioq->bio_unused = NULL;
}
static __inline void
bioq_insert_tail(struct bio_queue_head *bioq, struct bio *bio)
{
bioq->transition = NULL;
TAILQ_INSERT_TAIL(&bioq->queue, bio, bio_act);
}
static __inline void
bioq_remove(struct bio_queue_head *bioq, struct bio *bio)
{
if (bio == bioq->transition)
bioq->transition = TAILQ_NEXT(bio, bio_act);
TAILQ_REMOVE(&bioq->queue, bio, bio_act);
}
static __inline struct bio *
bioq_first(struct bio_queue_head *bioq)
{
return (TAILQ_FIRST(&bioq->queue));
}
static __inline struct bio *
bioq_takefirst(struct bio_queue_head *bioq)
{
struct bio *bp;
bp = TAILQ_FIRST(&bioq->queue);
if (bp != NULL)
bioq_remove(bioq, bp);
return (bp);
}
static __inline void
buf_act_advance(struct buf *bp)
{
if (bp->b_act_count > ACT_MAX - ACT_ADVANCE)
bp->b_act_count = ACT_MAX;
else
bp->b_act_count += ACT_ADVANCE;
}
static __inline void
buf_act_decline(struct buf *bp)
{
if (bp->b_act_count < ACT_DECLINE)
bp->b_act_count = 0;
else
bp->b_act_count -= ACT_DECLINE;
}
static __inline void
buf_dep_init(struct buf *bp)
{
bp->b_ops = NULL;
LIST_INIT(&bp->b_dep);
}
static __inline void
buf_deallocate(struct buf *bp)
{
struct bio_ops *ops = bp->b_ops;
KKASSERT(! LIST_EMPTY(&bp->b_dep));
if (ops)
ops->io_deallocate(bp);
}
static __inline int
buf_countdeps(struct buf *bp, int n)
{
struct bio_ops *ops = bp->b_ops;
int r;
if (ops) {
if (bp->b_vp == NULL || (bp->b_vp->v_flag & VKVABIO) == 0)
bkvasync_all(bp);
r = ops->io_countdeps(bp, n);
} else {
r = 0;
}
return(r);
}
static __inline void
buf_start(struct buf *bp)
{
struct bio_ops *ops = bp->b_ops;
if (ops)
ops->io_start(bp);
}
static __inline void
buf_complete(struct buf *bp)
{
struct bio_ops *ops = bp->b_ops;
if (ops)
ops->io_complete(bp);
}
static __inline int
buf_fsync(struct vnode *vp)
{
struct bio_ops *ops = vp->v_mount->mnt_bioops;
int r;
if (ops)
r = ops->io_fsync(vp);
else
r = 0;
return(r);
}
static __inline void
buf_movedeps(struct buf *bp1, struct buf *bp2)
{
struct bio_ops *ops = bp1->b_ops;
if (ops)
ops->io_movedeps(bp1, bp2);
}
static __inline int
buf_checkread(struct buf *bp)
{
struct bio_ops *ops = bp->b_ops;
if (ops)
return(ops->io_checkread(bp));
return(0);
}
static __inline int
buf_checkwrite(struct buf *bp)
{
struct bio_ops *ops = bp->b_ops;
if (ops) {
if (bp->b_vp == NULL || (bp->b_vp->v_flag & VKVABIO) == 0)
bkvasync_all(bp);
return(ops->io_checkwrite(bp));
}
return(0);
}
static __inline void
biodone_chain(struct bio *bio)
{
if (bio->bio_prev)
biodone(bio->bio_prev);
else
bpdone(bio->bio_buf, 1);
}
static __inline int
bread(struct vnode *vp, off_t loffset, int size, struct buf **bpp)
{
*bpp = NULL;
return(breadnx(vp, loffset, size, B_NOTMETA,
NULL, NULL, 0, bpp));
}
static __inline int
bread_kvabio(struct vnode *vp, off_t loffset, int size, struct buf **bpp)
{
*bpp = NULL;
return(breadnx(vp, loffset, size, B_NOTMETA | B_KVABIO,
NULL, NULL, 0, bpp));
}
static __inline int
breadn(struct vnode *vp, off_t loffset, int size, off_t *raoffset,
int *rabsize, int cnt, struct buf **bpp)
{
*bpp = NULL;
return(breadnx(vp, loffset, size, B_NOTMETA, raoffset,
rabsize, cnt, bpp));
}
static __inline int
cluster_read(struct vnode *vp, off_t filesize, off_t loffset,
int blksize, size_t minreq, size_t maxreq, struct buf **bpp)
{
*bpp = NULL;
return(cluster_readx(vp, filesize, loffset, blksize, B_NOTMETA,
minreq, maxreq, bpp));
}
static __inline int
cluster_read_kvabio(struct vnode *vp, off_t filesize, off_t loffset,
int blksize, size_t minreq, size_t maxreq, struct buf **bpp)
{
*bpp = NULL;
return(cluster_readx(vp, filesize, loffset, blksize,
B_NOTMETA | B_KVABIO,
minreq, maxreq, bpp));
}
#endif
#endif