From c7feb175725898650e653125977fd06936707337 Mon Sep 17 00:00:00 2001 From: phk Date: Wed, 3 May 2000 07:47:46 +0000 Subject: [PATCH] Convert the vm_pager_strategy() interface to take a struct bio instead of a struct buf. Don't try to examine B_ASYNC, it is a layering violation to do so. The only current user of this interface is vn(4) which, since it emulates a disk interface, operates on struct bio already. --- sys/dev/vn/vn.c | 2 - sys/sys/bio.h | 16 +++--- sys/sys/buf.h | 16 +++--- sys/vm/swap_pager.c | 132 ++++++++++++++++++-------------------------- sys/vm/vm_pager.c | 8 +-- sys/vm/vm_pager.h | 6 +- 6 files changed, 76 insertions(+), 104 deletions(-) diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c index 0ce3c0514822..f8ba7e9912b4 100644 --- a/sys/dev/vn/vn.c +++ b/sys/dev/vn/vn.c @@ -267,8 +267,6 @@ vnopen(dev_t dev, int flags, int mode, struct proc *p) * for vnode-backed vn's, and the new vm_pager_strategy() call for * vm_object-backed vn's. * - * Currently B_ASYNC is only partially handled - for OBJT_SWAP I/O only. - * * NOTE: bp->b_blkno is DEV_BSIZE'd. We must generate bp->b_pblkno for * our uio or vn_pager_strategy() call that is vn->sc_secsize'd */ diff --git a/sys/sys/bio.h b/sys/sys/bio.h index 15fe01458bab..60920a611890 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -174,10 +174,6 @@ struct buf { struct vm_page *b_pages[btoc(MAXPHYS)]; int b_npages; struct workhead b_dep; /* List of filesystem dependencies. */ - struct chain_info { /* buffer chaining */ - struct buf *parent; - int count; - } b_chain; }; #define b_spc b_pager.pg_spc @@ -230,8 +226,10 @@ struct buf { #define BIO_DELETE 4 #define BIO_FORMAT 8 -#define BIO_ERROR 0x00000001 -#define BIO_ORDERED 0x00000002 +#define BIO_ERROR 0x00000001 /* I/O error occurred. */ +#define BIO_ORDERED 0x00000002 /* Must guarantee I/O ordering */ +#define BIO_FLAG2 0x40000000 /* Available for local hacks */ +#define BIO_FLAG1 0x80000000 /* Available for local hacks */ #define B_AGE 0x00000001 /* Move to age queue when I/O done. */ #define B_NEEDCOMMIT 0x00000002 /* Append-write in progress. */ @@ -243,7 +241,7 @@ struct buf { #define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */ #define B_DONE 0x00000200 /* I/O completed. */ #define B_EINTR 0x00000400 /* I/O was interrupted */ -#define B_ERROR 0x00000800 /* I/O error occurred. */ +#define B_00000800 0x00000800 /* Available flag. */ #define B_SCANNED 0x00001000 /* VOP_FSYNC funcs mark written bufs */ #define B_INVAL 0x00002000 /* Does not contain valid info. */ #define B_LOCKED 0x00004000 /* Locked in core (not reusable). */ @@ -258,11 +256,11 @@ struct buf { #define B_WRITEINPROG 0x01000000 /* Write in progress. */ #define B_XXX 0x02000000 /* Debugging flag. */ #define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */ -#define B_ORDERED 0x08000000 /* Must guarantee I/O ordering */ +#define B_08000000 0x08000000 /* Available flag. */ #define B_RAM 0x10000000 /* Read ahead mark (flag) */ #define B_VMIO 0x20000000 /* VMIO flag */ #define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */ -#define B_AUTOCHAINDONE 0x80000000 /* Available flag */ +#define B_80000000 0x80000000 /* Available flag. */ #define PRINT_BUF_FLAGS "\20\40autochain\37cluster\36vmio\35ram\34ordered" \ "\33paging\32xxx\31writeinprog\30want\27relbuf\26dirty" \ diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 15fe01458bab..60920a611890 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -174,10 +174,6 @@ struct buf { struct vm_page *b_pages[btoc(MAXPHYS)]; int b_npages; struct workhead b_dep; /* List of filesystem dependencies. */ - struct chain_info { /* buffer chaining */ - struct buf *parent; - int count; - } b_chain; }; #define b_spc b_pager.pg_spc @@ -230,8 +226,10 @@ struct buf { #define BIO_DELETE 4 #define BIO_FORMAT 8 -#define BIO_ERROR 0x00000001 -#define BIO_ORDERED 0x00000002 +#define BIO_ERROR 0x00000001 /* I/O error occurred. */ +#define BIO_ORDERED 0x00000002 /* Must guarantee I/O ordering */ +#define BIO_FLAG2 0x40000000 /* Available for local hacks */ +#define BIO_FLAG1 0x80000000 /* Available for local hacks */ #define B_AGE 0x00000001 /* Move to age queue when I/O done. */ #define B_NEEDCOMMIT 0x00000002 /* Append-write in progress. */ @@ -243,7 +241,7 @@ struct buf { #define B_DELWRI 0x00000080 /* Delay I/O until buffer reused. */ #define B_DONE 0x00000200 /* I/O completed. */ #define B_EINTR 0x00000400 /* I/O was interrupted */ -#define B_ERROR 0x00000800 /* I/O error occurred. */ +#define B_00000800 0x00000800 /* Available flag. */ #define B_SCANNED 0x00001000 /* VOP_FSYNC funcs mark written bufs */ #define B_INVAL 0x00002000 /* Does not contain valid info. */ #define B_LOCKED 0x00004000 /* Locked in core (not reusable). */ @@ -258,11 +256,11 @@ struct buf { #define B_WRITEINPROG 0x01000000 /* Write in progress. */ #define B_XXX 0x02000000 /* Debugging flag. */ #define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */ -#define B_ORDERED 0x08000000 /* Must guarantee I/O ordering */ +#define B_08000000 0x08000000 /* Available flag. */ #define B_RAM 0x10000000 /* Read ahead mark (flag) */ #define B_VMIO 0x20000000 /* VMIO flag */ #define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */ -#define B_AUTOCHAINDONE 0x80000000 /* Available flag */ +#define B_80000000 0x80000000 /* Available flag. */ #define PRINT_BUF_FLAGS "\20\40autochain\37cluster\36vmio\35ram\34ordered" \ "\33paging\32xxx\31writeinprog\30want\27relbuf\26dirty" \ diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 48ba491487d3..473be9bdf719 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -152,7 +152,7 @@ static void swap_pager_dealloc __P((vm_object_t object)); static int swap_pager_getpages __P((vm_object_t, vm_page_t *, int, int)); static void swap_pager_init __P((void)); static void swap_pager_unswapped __P((vm_page_t)); -static void swap_pager_strategy __P((vm_object_t, struct buf *)); +static void swap_pager_strategy __P((vm_object_t, struct bio *)); struct pagerops swappagerops = { swap_pager_init, /* early system initialization of pager */ @@ -165,10 +165,9 @@ struct pagerops swappagerops = { swap_pager_strategy /* pager strategy call */ }; -static struct buf *getchainbuf(struct buf *bp, struct vnode *vp, int flags); +static struct buf *getchainbuf(struct bio *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); +static void waitchainbuf(struct bio *bp, int count, int done); /* * dmmax is in page-sized chunks with the new swap system. It was @@ -819,7 +818,7 @@ swap_pager_unswapped(m) */ static void -swap_pager_strategy(vm_object_t object, struct buf *bp) +swap_pager_strategy(vm_object_t object, struct bio *bp) { vm_pindex_t start; int count; @@ -827,12 +826,12 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) char *data; struct buf *nbp = NULL; - if (bp->b_bcount & PAGE_MASK) { - bp->b_error = EINVAL; - bp->b_ioflags |= BIO_ERROR; - bp->b_flags |= B_INVAL; - bufdone(bp); - printf("swap_pager_strategy: bp %p b_vp %p blk %d size %d, not page bounded\n", bp, bp->b_vp, (int)bp->b_pblkno, (int)bp->b_bcount); + /* XXX: KASSERT instead ? */ + if (bp->bio_bcount & PAGE_MASK) { + bp->bio_error = EINVAL; + bp->bio_flags |= BIO_ERROR; + biodone(bp); + printf("swap_pager_strategy: bp %p blk %d size %d, not page bounded\n", bp, (int)bp->bio_pblkno, (int)bp->bio_bcount); return; } @@ -840,13 +839,13 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) * Clear error indication, initialize page index, count, data pointer. */ - bp->b_error = 0; - bp->b_ioflags &= ~BIO_ERROR; - bp->b_resid = bp->b_bcount; + bp->bio_error = 0; + bp->bio_flags &= ~BIO_ERROR; + bp->bio_resid = bp->bio_bcount; - start = bp->b_pblkno; - count = howmany(bp->b_bcount, PAGE_SIZE); - data = bp->b_data; + start = bp->bio_pblkno; + count = howmany(bp->bio_bcount, PAGE_SIZE); + data = bp->bio_data; s = splvm(); @@ -854,15 +853,15 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) * Deal with BIO_DELETE */ - if (bp->b_iocmd == BIO_DELETE) { + if (bp->bio_cmd == BIO_DELETE) { /* * FREE PAGE(s) - destroy underlying swap that is no longer * needed. */ swp_pager_meta_free(object, start, count); splx(s); - bp->b_resid = 0; - bufdone(bp); + bp->bio_resid = 0; + biodone(bp); return; } @@ -879,11 +878,11 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) */ blk = swp_pager_meta_ctl(object, start, 0); - if ((blk == SWAPBLK_NONE) && (bp->b_iocmd == BIO_WRITE)) { + if ((blk == SWAPBLK_NONE) && (bp->bio_cmd == BIO_WRITE)) { blk = swp_pager_getswapspace(1); if (blk == SWAPBLK_NONE) { - bp->b_error = ENOMEM; - bp->b_ioflags |= BIO_ERROR; + bp->bio_error = ENOMEM; + bp->bio_flags |= BIO_ERROR; break; } swp_pager_meta_build(object, start, blk); @@ -904,7 +903,7 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) ) ) { splx(s); - if (bp->b_iocmd == BIO_READ) { + if (bp->bio_cmd == BIO_READ) { ++cnt.v_swapin; cnt.v_swappgsin += btoc(nbp->b_bcount); } else { @@ -929,10 +928,10 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) * even if chain ops are in progress. */ bzero(data, PAGE_SIZE); - bp->b_resid -= PAGE_SIZE; + bp->bio_resid -= PAGE_SIZE; } else { if (nbp == NULL) { - nbp = getchainbuf(bp, swapdev_vp, (bp->b_iocmd == BIO_READ) | B_ASYNC); + nbp = getchainbuf(bp, swapdev_vp, B_ASYNC); nbp->b_blkno = blk; nbp->b_bcount = 0; nbp->b_data = data; @@ -951,8 +950,6 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) splx(s); if (nbp) { - if ((bp->b_flags & B_ASYNC) == 0) - nbp->b_flags &= ~B_ASYNC; if (nbp->b_iocmd == BIO_READ) { ++cnt.v_swapin; cnt.v_swappgsin += btoc(nbp->b_bcount); @@ -969,11 +966,7 @@ swap_pager_strategy(vm_object_t object, struct buf *bp) * Wait for completion. */ - if (bp->b_flags & B_ASYNC) { - autochaindone(bp); - } else { - waitchainbuf(bp, 0, 1); - } + waitchainbuf(bp, 0, 1); } /* @@ -1976,32 +1969,27 @@ swp_pager_meta_ctl( static void vm_pager_chain_iodone(struct buf *nbp) { - struct buf *bp; + struct bio *bp; + u_int *count; - if ((bp = nbp->b_chain.parent) != NULL) { + bp = nbp->b_caller1; + count = (u_int *)&(bp->bio_caller1); + if (bp != NULL) { if (nbp->b_ioflags & BIO_ERROR) { - bp->b_ioflags |= BIO_ERROR; - bp->b_error = nbp->b_error; + bp->bio_flags |= BIO_ERROR; + bp->bio_error = nbp->b_error; } else if (nbp->b_resid != 0) { - bp->b_ioflags |= BIO_ERROR; - bp->b_error = EINVAL; + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EINVAL; } else { - bp->b_resid -= nbp->b_bcount; + bp->bio_resid -= nbp->b_bcount; } - nbp->b_chain.parent = NULL; - --bp->b_chain.count; - if (bp->b_flags & B_WANT) { - bp->b_flags &= ~B_WANT; + nbp->b_caller1 = NULL; + --(*count); + if (bp->bio_flags & BIO_FLAG1) { + bp->bio_flags &= ~BIO_FLAG1; 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; @@ -2017,17 +2005,19 @@ vm_pager_chain_iodone(struct buf *nbp) */ struct buf * -getchainbuf(struct buf *bp, struct vnode *vp, int flags) +getchainbuf(struct bio *bp, struct vnode *vp, int flags) { struct buf *nbp = getpbuf(NULL); + u_int *count = (u_int *)&(bp->bio_caller1); - nbp->b_chain.parent = bp; - ++bp->b_chain.count; + nbp->b_caller1 = bp; + ++(*count); - if (bp->b_chain.count > 4) + if (*count > 4) waitchainbuf(bp, 4, 0); - nbp->b_ioflags = bp->b_ioflags & BIO_ORDERED; + nbp->b_iocmd = bp->bio_cmd; + nbp->b_ioflags = bp->bio_flags & BIO_ORDERED; nbp->b_flags = flags; nbp->b_rcred = nbp->b_wcred = proc0.p_ucred; nbp->b_iodone = vm_pager_chain_iodone; @@ -2055,35 +2045,23 @@ flushchainbuf(struct buf *nbp) } void -waitchainbuf(struct buf *bp, int count, int done) +waitchainbuf(struct bio *bp, int limit, int done) { int s; + u_int *count = (u_int *)&(bp->bio_caller1); s = splbio(); - while (bp->b_chain.count > count) { - bp->b_flags |= B_WANT; + while (*count > limit) { + bp->bio_flags |= BIO_FLAG1; 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; + if (bp->bio_resid != 0 && !(bp->bio_flags & BIO_ERROR)) { + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EINVAL; } - bufdone(bp); + biodone(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); -} - diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c index 84e61652a8b9..49c459a905e3 100644 --- a/sys/vm/vm_pager.c +++ b/sys/vm/vm_pager.c @@ -262,14 +262,14 @@ vm_pager_deallocate(object) */ void -vm_pager_strategy(vm_object_t object, struct buf *bp) +vm_pager_strategy(vm_object_t object, struct bio *bp) { if (pagertab[object->type]->pgo_strategy) { (*pagertab[object->type]->pgo_strategy)(object, bp); } else { - bp->b_ioflags |= BIO_ERROR; - bp->b_error = ENXIO; - bufdone(bp); + bp->bio_flags |= BIO_ERROR; + bp->bio_error = ENXIO; + biodone(bp); } } diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h index a10c790027a9..df0befa10ff1 100644 --- a/sys/vm/vm_pager.h +++ b/sys/vm/vm_pager.h @@ -50,7 +50,7 @@ TAILQ_HEAD(pagerlst, vm_object); -struct buf; +struct bio; struct pagerops { void (*pgo_init) __P((void)); /* Initialize pager. */ @@ -60,7 +60,7 @@ struct pagerops { void (*pgo_putpages) __P((vm_object_t, vm_page_t *, int, int, int *)); /* Put (write) page. */ boolean_t (*pgo_haspage) __P((vm_object_t, vm_pindex_t, int *, int *)); /* Does pager have page? */ void (*pgo_pageunswapped) __P((vm_page_t)); - void (*pgo_strategy) __P((vm_object_t, struct buf *)); + void (*pgo_strategy) __P((vm_object_t, struct bio *)); }; /* @@ -104,7 +104,7 @@ vm_offset_t vm_pager_map_page __P((vm_page_t)); 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)); +void vm_pager_strategy __P((vm_object_t object, struct bio *bp)); /* * vm_page_get_pages: