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
|
int
|
||||||
physio(struct cdev *dev, struct uio *uio, int ioflag)
|
physio(struct cdev *dev, struct uio *uio, int ioflag)
|
||||||
{
|
{
|
||||||
int i;
|
struct buf *bp;
|
||||||
int error;
|
struct cdevsw *csw;
|
||||||
caddr_t sa;
|
caddr_t sa;
|
||||||
u_int iolen;
|
u_int iolen;
|
||||||
struct buf *bp;
|
int error, i, mapped;
|
||||||
|
|
||||||
/* Keep the process UPAGES from being swapped. XXX: why ? */
|
/* Keep the process UPAGES from being swapped. XXX: why ? */
|
||||||
PHOLD(curproc);
|
PHOLD(curproc);
|
||||||
@ -91,11 +91,8 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
|
|||||||
|
|
||||||
bp->b_blkno = btodb(bp->b_offset);
|
bp->b_blkno = btodb(bp->b_offset);
|
||||||
|
|
||||||
if (uio->uio_segflg == UIO_USERSPACE) {
|
|
||||||
struct cdevsw *csw;
|
|
||||||
int mapped;
|
|
||||||
|
|
||||||
csw = dev->si_devsw;
|
csw = dev->si_devsw;
|
||||||
|
if (uio->uio_segflg == UIO_USERSPACE) {
|
||||||
if (csw != NULL &&
|
if (csw != NULL &&
|
||||||
(csw->d_flags & D_UNMAPPED_IO) != 0)
|
(csw->d_flags & D_UNMAPPED_IO) != 0)
|
||||||
mapped = 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)
|
if (uio->uio_rw == UIO_READ)
|
||||||
bwait(bp, PRIBIO, "physrd");
|
bwait(bp, PRIBIO, "physrd");
|
||||||
else
|
else
|
||||||
|
@ -3687,11 +3687,34 @@ void
|
|||||||
dev_strategy(struct cdev *dev, struct buf *bp)
|
dev_strategy(struct cdev *dev, struct buf *bp)
|
||||||
{
|
{
|
||||||
struct cdevsw *csw;
|
struct cdevsw *csw;
|
||||||
struct bio *bip;
|
|
||||||
int ref;
|
int ref;
|
||||||
|
|
||||||
if ((!bp->b_iocmd) || (bp->b_iocmd & (bp->b_iocmd - 1)))
|
KASSERT(dev->si_refcount > 0,
|
||||||
panic("b_iocmd botch");
|
("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 (;;) {
|
for (;;) {
|
||||||
bip = g_new_bio();
|
bip = g_new_bio();
|
||||||
if (bip != NULL)
|
if (bip != NULL)
|
||||||
@ -3707,19 +3730,7 @@ dev_strategy(struct cdev *dev, struct buf *bp)
|
|||||||
bip->bio_done = bufdonebio;
|
bip->bio_done = bufdonebio;
|
||||||
bip->bio_caller2 = bp;
|
bip->bio_caller2 = bp;
|
||||||
bip->bio_dev = dev;
|
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);
|
(*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_refl(struct cdev *dev);
|
||||||
void dev_rel(struct cdev *dev);
|
void dev_rel(struct cdev *dev);
|
||||||
void dev_strategy(struct cdev *dev, struct buf *bp);
|
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,
|
struct cdev *make_dev(struct cdevsw *_devsw, int _unit, uid_t _uid, gid_t _gid,
|
||||||
int _perms, const char *_fmt, ...) __printflike(6, 7);
|
int _perms, const char *_fmt, ...) __printflike(6, 7);
|
||||||
struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit,
|
struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user