diff options
author | kib <kib@FreeBSD.org> | 2013-03-27 11:34:27 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-03-27 11:34:27 +0000 |
commit | 448e7c12908c8a8680ec5f93934de43b8ad1a06f (patch) | |
tree | 036654e19fbde1423bfd8d644566101fc38a8e7b /sys/kern | |
parent | df3795022f641dd4da863c0f0ff258a789720c23 (diff) | |
download | FreeBSD-src-448e7c12908c8a8680ec5f93934de43b8ad1a06f.zip FreeBSD-src-448e7c12908c8a8680ec5f93934de43b8ad1a06f.tar.gz |
Add dev_strategy_csw() function, which is similar to dev_strategy()
but assumes that a thread reference was already obtained on the passed
device. Use the function from physio(), to avoid two extra dev_mtx
lock and unlock. Note that physio() is always used as the cdevsw
method, or is called from a cdevsw method, and the caller already owns
the reference.
dev_strategy() is left to keep KPI intact, but now it is implemented
as a wrapper around dev_strategy_csw().
Do some style cleanup in physio().
Requested and reviewed by: kan (previous version)
Sponsored by: The FreeBSD Foundation
MFC after: 2 weeks
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_physio.c | 13 | ||||
-rw-r--r-- | sys/kern/vfs_bio.c | 41 |
2 files changed, 31 insertions, 23 deletions
diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c index 1eb5b8f..1387c8e 100644 --- a/sys/kern/kern_physio.c +++ b/sys/kern/kern_physio.c @@ -34,11 +34,11 @@ __FBSDID("$FreeBSD$"); int physio(struct cdev *dev, struct uio *uio, int ioflag) { - int i; - int error; + struct buf *bp; + struct cdevsw *csw; caddr_t sa; u_int iolen; - struct buf *bp; + int error, i, mapped; /* Keep the process UPAGES from being swapped. XXX: why ? */ PHOLD(curproc); @@ -91,11 +91,8 @@ physio(struct cdev *dev, struct uio *uio, int ioflag) bp->b_blkno = btodb(bp->b_offset); + csw = dev->si_devsw; if (uio->uio_segflg == UIO_USERSPACE) { - struct cdevsw *csw; - int mapped; - - csw = dev->si_devsw; if (csw != NULL && (csw->d_flags & D_UNMAPPED_IO) != 0) mapped = 0; @@ -107,7 +104,7 @@ physio(struct cdev *dev, struct uio *uio, int ioflag) } } - dev_strategy(dev, bp); + dev_strategy_csw(dev, csw, bp); if (uio->uio_rw == UIO_READ) bwait(bp, PRIBIO, "physrd"); else diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 7b1aa8e..db7d681 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3687,11 +3687,34 @@ void dev_strategy(struct cdev *dev, struct buf *bp) { struct cdevsw *csw; - struct bio *bip; int ref; - if ((!bp->b_iocmd) || (bp->b_iocmd & (bp->b_iocmd - 1))) - panic("b_iocmd botch"); + KASSERT(dev->si_refcount > 0, + ("dev_strategy on un-referenced struct cdev *(%s) %p", + devtoname(dev), dev)); + + csw = dev_refthread(dev, &ref); + dev_strategy_csw(dev, csw, bp); + dev_relthread(dev, ref); +} + +void +dev_strategy_csw(struct cdev *dev, struct cdevsw *csw, struct buf *bp) +{ + struct bio *bip; + + KASSERT(bp->b_iocmd == BIO_READ || bp->b_iocmd == BIO_WRITE, + ("b_iocmd botch")); + KASSERT(((dev->si_flags & SI_ETERNAL) != 0 && csw != NULL) || + dev->si_threadcount > 0, + ("dev_strategy_csw threadcount cdev *(%s) %p", devtoname(dev), + dev)); + if (csw == NULL) { + bp->b_error = ENXIO; + bp->b_ioflags = BIO_ERROR; + bufdone(bp); + return; + } for (;;) { bip = g_new_bio(); if (bip != NULL) @@ -3707,19 +3730,7 @@ dev_strategy(struct cdev *dev, struct buf *bp) bip->bio_done = bufdonebio; bip->bio_caller2 = bp; bip->bio_dev = dev; - KASSERT(dev->si_refcount > 0, - ("dev_strategy on un-referenced struct cdev *(%s)", - devtoname(dev))); - csw = dev_refthread(dev, &ref); - if (csw == NULL) { - g_destroy_bio(bip); - bp->b_error = ENXIO; - bp->b_ioflags = BIO_ERROR; - bufdone(bp); - return; - } (*csw->d_strategy)(bip); - dev_relthread(dev, ref); } /* |