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:
parent
88c8c0a70f
commit
d1e99f43ed
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user