mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-04 10:19:26 +00:00
Move and staticize the bufchain functions so they become local to the
only piece of code using them. This will ease a rewrite of them.
This commit is contained in:
parent
23f282aa31
commit
e4057dbdb0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=59866
@ -165,6 +165,11 @@ struct pagerops swappagerops = {
|
||||
swap_pager_strategy /* pager strategy call */
|
||||
};
|
||||
|
||||
static struct buf *getchainbuf(struct buf *bp, struct vnode *vp, int flags);
|
||||
static void flushchainbuf(struct buf *nbp);
|
||||
static void waitchainbuf(struct buf *bp, int count, int done);
|
||||
static void autochaindone(struct buf *bp);
|
||||
|
||||
/*
|
||||
* dmmax is in page-sized chunks with the new swap system. It was
|
||||
* dev-bsized chunks in the old.
|
||||
@ -1950,3 +1955,135 @@ swp_pager_meta_ctl(
|
||||
return(r1);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* CHAINING FUNCTIONS *
|
||||
********************************************************
|
||||
*
|
||||
* These functions support recursion of I/O operations
|
||||
* on bp's, typically by chaining one or more 'child' bp's
|
||||
* to the parent. Synchronous, asynchronous, and semi-synchronous
|
||||
* chaining is possible.
|
||||
*/
|
||||
|
||||
/*
|
||||
* vm_pager_chain_iodone:
|
||||
*
|
||||
* io completion routine for child bp. Currently we fudge a bit
|
||||
* on dealing with b_resid. Since users of these routines may issue
|
||||
* multiple children simultaneously, sequencing of the error can be lost.
|
||||
*/
|
||||
|
||||
static void
|
||||
vm_pager_chain_iodone(struct buf *nbp)
|
||||
{
|
||||
struct buf *bp;
|
||||
|
||||
if ((bp = nbp->b_chain.parent) != NULL) {
|
||||
if (nbp->b_ioflags & BIO_ERROR) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = nbp->b_error;
|
||||
} else if (nbp->b_resid != 0) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = EINVAL;
|
||||
} else {
|
||||
bp->b_resid -= nbp->b_bcount;
|
||||
}
|
||||
nbp->b_chain.parent = NULL;
|
||||
--bp->b_chain.count;
|
||||
if (bp->b_flags & B_WANT) {
|
||||
bp->b_flags &= ~B_WANT;
|
||||
wakeup(bp);
|
||||
}
|
||||
if (!bp->b_chain.count && (bp->b_flags & B_AUTOCHAINDONE)) {
|
||||
bp->b_flags &= ~B_AUTOCHAINDONE;
|
||||
if (bp->b_resid != 0 && !(bp->b_ioflags & BIO_ERROR)) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = EINVAL;
|
||||
}
|
||||
bufdone(bp);
|
||||
}
|
||||
}
|
||||
nbp->b_flags |= B_DONE;
|
||||
nbp->b_flags &= ~B_ASYNC;
|
||||
relpbuf(nbp, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* getchainbuf:
|
||||
*
|
||||
* Obtain a physical buffer and chain it to its parent buffer. When
|
||||
* I/O completes, the parent buffer will be B_SIGNAL'd. Errors are
|
||||
* automatically propagated to the parent
|
||||
*/
|
||||
|
||||
struct buf *
|
||||
getchainbuf(struct buf *bp, struct vnode *vp, int flags)
|
||||
{
|
||||
struct buf *nbp = getpbuf(NULL);
|
||||
|
||||
nbp->b_chain.parent = bp;
|
||||
++bp->b_chain.count;
|
||||
|
||||
if (bp->b_chain.count > 4)
|
||||
waitchainbuf(bp, 4, 0);
|
||||
|
||||
nbp->b_ioflags = bp->b_ioflags & BIO_ORDERED;
|
||||
nbp->b_flags = flags;
|
||||
nbp->b_rcred = nbp->b_wcred = proc0.p_ucred;
|
||||
nbp->b_iodone = vm_pager_chain_iodone;
|
||||
|
||||
crhold(nbp->b_rcred);
|
||||
crhold(nbp->b_wcred);
|
||||
|
||||
if (vp)
|
||||
pbgetvp(vp, nbp);
|
||||
return(nbp);
|
||||
}
|
||||
|
||||
void
|
||||
flushchainbuf(struct buf *nbp)
|
||||
{
|
||||
if (nbp->b_bcount) {
|
||||
nbp->b_bufsize = nbp->b_bcount;
|
||||
if (nbp->b_iocmd == BIO_WRITE)
|
||||
nbp->b_dirtyend = nbp->b_bcount;
|
||||
BUF_KERNPROC(nbp);
|
||||
BUF_STRATEGY(nbp);
|
||||
} else {
|
||||
bufdone(nbp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
waitchainbuf(struct buf *bp, int count, int done)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
while (bp->b_chain.count > count) {
|
||||
bp->b_flags |= B_WANT;
|
||||
tsleep(bp, PRIBIO + 4, "bpchain", 0);
|
||||
}
|
||||
if (done) {
|
||||
if (bp->b_resid != 0 && !(bp->b_ioflags & BIO_ERROR)) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = EINVAL;
|
||||
}
|
||||
bufdone(bp);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
autochaindone(struct buf *bp)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if (bp->b_chain.count == 0)
|
||||
bufdone(bp);
|
||||
else
|
||||
bp->b_flags |= B_AUTOCHAINDONE;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
@ -472,136 +472,3 @@ relpbuf(bp, pfreecnt)
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* CHAINING FUNCTIONS *
|
||||
********************************************************
|
||||
*
|
||||
* These functions support recursion of I/O operations
|
||||
* on bp's, typically by chaining one or more 'child' bp's
|
||||
* to the parent. Synchronous, asynchronous, and semi-synchronous
|
||||
* chaining is possible.
|
||||
*/
|
||||
|
||||
/*
|
||||
* vm_pager_chain_iodone:
|
||||
*
|
||||
* io completion routine for child bp. Currently we fudge a bit
|
||||
* on dealing with b_resid. Since users of these routines may issue
|
||||
* multiple children simultaneously, sequencing of the error can be lost.
|
||||
*/
|
||||
|
||||
static void
|
||||
vm_pager_chain_iodone(struct buf *nbp)
|
||||
{
|
||||
struct buf *bp;
|
||||
|
||||
if ((bp = nbp->b_chain.parent) != NULL) {
|
||||
if (nbp->b_ioflags & BIO_ERROR) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = nbp->b_error;
|
||||
} else if (nbp->b_resid != 0) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = EINVAL;
|
||||
} else {
|
||||
bp->b_resid -= nbp->b_bcount;
|
||||
}
|
||||
nbp->b_chain.parent = NULL;
|
||||
--bp->b_chain.count;
|
||||
if (bp->b_flags & B_WANT) {
|
||||
bp->b_flags &= ~B_WANT;
|
||||
wakeup(bp);
|
||||
}
|
||||
if (!bp->b_chain.count && (bp->b_flags & B_AUTOCHAINDONE)) {
|
||||
bp->b_flags &= ~B_AUTOCHAINDONE;
|
||||
if (bp->b_resid != 0 && !(bp->b_ioflags & BIO_ERROR)) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = EINVAL;
|
||||
}
|
||||
bufdone(bp);
|
||||
}
|
||||
}
|
||||
nbp->b_flags |= B_DONE;
|
||||
nbp->b_flags &= ~B_ASYNC;
|
||||
relpbuf(nbp, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* getchainbuf:
|
||||
*
|
||||
* Obtain a physical buffer and chain it to its parent buffer. When
|
||||
* I/O completes, the parent buffer will be B_SIGNAL'd. Errors are
|
||||
* automatically propagated to the parent
|
||||
*/
|
||||
|
||||
struct buf *
|
||||
getchainbuf(struct buf *bp, struct vnode *vp, int flags)
|
||||
{
|
||||
struct buf *nbp = getpbuf(NULL);
|
||||
|
||||
nbp->b_chain.parent = bp;
|
||||
++bp->b_chain.count;
|
||||
|
||||
if (bp->b_chain.count > 4)
|
||||
waitchainbuf(bp, 4, 0);
|
||||
|
||||
nbp->b_ioflags = bp->b_ioflags & BIO_ORDERED;
|
||||
nbp->b_flags = flags;
|
||||
nbp->b_rcred = nbp->b_wcred = proc0.p_ucred;
|
||||
nbp->b_iodone = vm_pager_chain_iodone;
|
||||
|
||||
crhold(nbp->b_rcred);
|
||||
crhold(nbp->b_wcred);
|
||||
|
||||
if (vp)
|
||||
pbgetvp(vp, nbp);
|
||||
return(nbp);
|
||||
}
|
||||
|
||||
void
|
||||
flushchainbuf(struct buf *nbp)
|
||||
{
|
||||
if (nbp->b_bcount) {
|
||||
nbp->b_bufsize = nbp->b_bcount;
|
||||
if (nbp->b_iocmd == BIO_WRITE)
|
||||
nbp->b_dirtyend = nbp->b_bcount;
|
||||
BUF_KERNPROC(nbp);
|
||||
BUF_STRATEGY(nbp);
|
||||
} else {
|
||||
bufdone(nbp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
waitchainbuf(struct buf *bp, int count, int done)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
while (bp->b_chain.count > count) {
|
||||
bp->b_flags |= B_WANT;
|
||||
tsleep(bp, PRIBIO + 4, "bpchain", 0);
|
||||
}
|
||||
if (done) {
|
||||
if (bp->b_resid != 0 && !(bp->b_ioflags & BIO_ERROR)) {
|
||||
bp->b_ioflags |= BIO_ERROR;
|
||||
bp->b_error = EINVAL;
|
||||
}
|
||||
bufdone(bp);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
autochaindone(struct buf *bp)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
if (bp->b_chain.count == 0)
|
||||
bufdone(bp);
|
||||
else
|
||||
bp->b_flags |= B_AUTOCHAINDONE;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
@ -105,10 +105,6 @@ void vm_pager_sync __P((void));
|
||||
void vm_pager_unmap_pages __P((vm_offset_t, int));
|
||||
void vm_pager_unmap_page __P((vm_offset_t));
|
||||
void vm_pager_strategy __P((vm_object_t object, struct buf *bp));
|
||||
struct buf *getchainbuf(struct buf *bp, struct vnode *vp, int flags);
|
||||
void flushchainbuf(struct buf *nbp);
|
||||
void waitchainbuf(struct buf *bp, int count, int done);
|
||||
void autochaindone(struct buf *bp);
|
||||
|
||||
/*
|
||||
* vm_page_get_pages:
|
||||
|
Loading…
Reference in New Issue
Block a user