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
This commit is contained in:
Konstantin Belousov 2013-03-27 11:34:27 +00:00
parent 88c8c0a70f
commit d1e99f43ed
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248792
3 changed files with 32 additions and 23 deletions

View File

@ -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

View File

@ -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);
}
/*

View File

@ -255,6 +255,7 @@ void dev_ref(struct cdev *dev);
void dev_refl(struct cdev *dev);
void dev_rel(struct cdev *dev);
void dev_strategy(struct cdev *dev, struct buf *bp);
void dev_strategy_csw(struct cdev *dev, struct cdevsw *csw, struct buf *bp);
struct cdev *make_dev(struct cdevsw *_devsw, int _unit, uid_t _uid, gid_t _gid,
int _perms, const char *_fmt, ...) __printflike(6, 7);
struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit,