summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_bio.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-03-27 11:34:27 +0000
committerkib <kib@FreeBSD.org>2013-03-27 11:34:27 +0000
commit448e7c12908c8a8680ec5f93934de43b8ad1a06f (patch)
tree036654e19fbde1423bfd8d644566101fc38a8e7b /sys/kern/vfs_bio.c
parentdf3795022f641dd4da863c0f0ff258a789720c23 (diff)
downloadFreeBSD-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/vfs_bio.c')
-rw-r--r--sys/kern/vfs_bio.c41
1 files changed, 26 insertions, 15 deletions
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);
}
/*
OpenPOWER on IntegriCloud