svn commit: r212229 - in stable/8/sys: fs/devfs kern sys vm
Konstantin Belousov
kib at FreeBSD.org
Sun Sep 5 14:27:56 UTC 2010
Author: kib
Date: Sun Sep 5 14:27:55 2010
New Revision: 212229
URL: http://svn.freebsd.org/changeset/base/212229
Log:
MFC r210923:
Add new make_dev_p(9) flag MAKEDEV_ETERNAL to inform devfs that created
cdev will never be destroyed. Propagate the flag to devfs vnodes as
VV_ETERNVALDEV. Use the flags to avoid acquiring devmtx and taking a
thread reference on such nodes.
Modified:
stable/8/sys/fs/devfs/devfs_rule.c
stable/8/sys/fs/devfs/devfs_vnops.c
stable/8/sys/kern/kern_conf.c
stable/8/sys/kern/tty.c
stable/8/sys/kern/vfs_bio.c
stable/8/sys/sys/conf.h
stable/8/sys/sys/vnode.h
stable/8/sys/vm/device_pager.c
stable/8/sys/vm/vm_mmap.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/fs/devfs/devfs_rule.c
==============================================================================
--- stable/8/sys/fs/devfs/devfs_rule.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/fs/devfs/devfs_rule.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -528,6 +528,7 @@ devfs_rule_match(struct devfs_krule *dk,
struct devfs_rule *dr = &dk->dk_rule;
struct cdev *dev;
struct cdevsw *dsw;
+ int ref;
dev = devfs_rule_getdev(de);
/*
@@ -545,14 +546,14 @@ devfs_rule_match(struct devfs_krule *dk,
if (dr->dr_icond & DRC_DSWFLAGS) {
if (dev == NULL)
return (0);
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (0);
if ((dsw->d_flags & dr->dr_dswflags) == 0) {
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (0);
}
- dev_relthread(dev);
+ dev_relthread(dev, ref);
}
if (dr->dr_icond & DRC_PATHPTRN)
if (!devfs_rule_matchpath(dk, de))
Modified: stable/8/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- stable/8/sys/fs/devfs/devfs_vnops.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/fs/devfs/devfs_vnops.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -82,13 +82,14 @@ struct mtx cdevpriv_mtx;
MTX_SYSINIT(cdevpriv_mtx, &cdevpriv_mtx, "cdevpriv lock", MTX_DEF);
static int
-devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp)
+devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp,
+ int *ref)
{
- *dswp = devvn_refthread(fp->f_vnode, devp);
+ *dswp = devvn_refthread(fp->f_vnode, devp, ref);
if (*devp != fp->f_data) {
if (*dswp != NULL)
- dev_relthread(*devp);
+ dev_relthread(*devp, *ref);
return (ENXIO);
}
KASSERT((*devp)->si_refcount > 0,
@@ -401,6 +402,8 @@ devfs_allocv(struct devfs_dirent *de, st
vp->v_vflag |= VV_ISTTY;
dev_unlock();
VI_UNLOCK(vp);
+ if ((dev->si_flags & SI_ETERNAL) != 0)
+ vp->v_vflag |= VV_ETERNALDEV;
vp->v_op = &devfs_specops;
} else if (de->de_dirent->d_type == DT_DIR) {
vp->v_type = VDIR;
@@ -465,7 +468,7 @@ devfs_close(struct vop_close_args *ap)
struct thread *td = ap->a_td;
struct cdev *dev = vp->v_rdev;
struct cdevsw *dsw;
- int vp_locked, error;
+ int vp_locked, error, ref;
/*
* XXX: Don't call d_close() if we were called because of
@@ -507,7 +510,7 @@ devfs_close(struct vop_close_args *ap)
* sum of the reference counts on all the aliased
* vnodes descends to one, we are on last close.
*/
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
VI_LOCK(vp);
@@ -517,7 +520,7 @@ devfs_close(struct vop_close_args *ap)
/* Keep device updated on status. */
} else if (count_dev(dev) > 1) {
VI_UNLOCK(vp);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (0);
}
vholdl(vp);
@@ -527,7 +530,7 @@ devfs_close(struct vop_close_args *ap)
KASSERT(dev->si_refcount > 0,
("devfs_close() on un-referenced struct cdev *(%s)", devtoname(dev)));
error = dsw->d_close(dev, ap->a_fflag, S_IFCHR, td);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
vn_lock(vp, vp_locked | LK_RETRY);
vdrop(vp);
return (error);
@@ -645,20 +648,20 @@ devfs_ioctl_f(struct file *fp, u_long co
struct cdevsw *dsw;
struct vnode *vp;
struct vnode *vpold;
- int error, i;
+ int error, i, ref;
const char *p;
struct fiodgname_arg *fgn;
struct file *fpop;
fpop = td->td_fpop;
- error = devfs_fp_check(fp, &dev, &dsw);
+ error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
return (error);
if (com == FIODTYPE) {
*(int *)data = dsw->d_flags & D_TYPEMASK;
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (0);
} else if (com == FIODGNAME) {
fgn = data;
@@ -669,12 +672,12 @@ devfs_ioctl_f(struct file *fp, u_long co
else
error = copyout(p, fgn->buf, i);
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (error);
}
error = dsw->d_ioctl(dev, com, data, fp->f_flag, td);
td->td_fpop = NULL;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
if (error == ENOIOCTL)
error = ENOTTY;
if (error == 0 && com == TIOCSCTTY) {
@@ -708,18 +711,18 @@ devfs_kqfilter_f(struct file *fp, struct
{
struct cdev *dev;
struct cdevsw *dsw;
- int error;
+ int error, ref;
struct file *fpop;
struct thread *td;
td = curthread;
fpop = td->td_fpop;
- error = devfs_fp_check(fp, &dev, &dsw);
+ error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
return (error);
error = dsw->d_kqfilter(dev, kn);
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (error);
}
@@ -956,7 +959,7 @@ devfs_open(struct vop_open_args *ap)
struct vnode *vp = ap->a_vp;
struct cdev *dev = vp->v_rdev;
struct file *fp = ap->a_fp;
- int error, vlocked;
+ int error, ref, vlocked;
struct cdevsw *dsw;
struct file *fpop;
@@ -970,7 +973,7 @@ devfs_open(struct vop_open_args *ap)
if (dev->si_iosize_max == 0)
dev->si_iosize_max = DFLTPHYS;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
@@ -990,7 +993,7 @@ devfs_open(struct vop_open_args *ap)
td->td_fpop = fpop;
vn_lock(vp, vlocked | LK_RETRY);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
if (error)
return (error);
@@ -1033,16 +1036,16 @@ devfs_poll_f(struct file *fp, int events
{
struct cdev *dev;
struct cdevsw *dsw;
- int error;
+ int error, ref;
struct file *fpop;
fpop = td->td_fpop;
- error = devfs_fp_check(fp, &dev, &dsw);
+ error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
return (poll_no_poll(events));
error = dsw->d_poll(dev, events, td);
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return(error);
}
@@ -1062,12 +1065,12 @@ static int
devfs_read_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
{
struct cdev *dev;
- int ioflag, error, resid;
+ int ioflag, error, ref, resid;
struct cdevsw *dsw;
struct file *fpop;
fpop = td->td_fpop;
- error = devfs_fp_check(fp, &dev, &dsw);
+ error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
return (error);
resid = uio->uio_resid;
@@ -1082,7 +1085,7 @@ devfs_read_f(struct file *fp, struct uio
if (uio->uio_resid != resid || (error == 0 && resid != 0))
vfs_timestamp(&dev->si_atime);
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
if ((flags & FOF_OFFSET) == 0)
fp->f_offset = uio->uio_offset;
@@ -1505,12 +1508,12 @@ static int
devfs_write_f(struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td)
{
struct cdev *dev;
- int error, ioflag, resid;
+ int error, ioflag, ref, resid;
struct cdevsw *dsw;
struct file *fpop;
fpop = td->td_fpop;
- error = devfs_fp_check(fp, &dev, &dsw);
+ error = devfs_fp_check(fp, &dev, &dsw, &ref);
if (error)
return (error);
KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td));
@@ -1528,7 +1531,7 @@ devfs_write_f(struct file *fp, struct ui
dev->si_mtime = dev->si_ctime;
}
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
if ((flags & FOF_OFFSET) == 0)
fp->f_offset = uio->uio_offset;
Modified: stable/8/sys/kern/kern_conf.c
==============================================================================
--- stable/8/sys/kern/kern_conf.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/kern/kern_conf.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -177,12 +177,16 @@ dev_rel(struct cdev *dev)
}
struct cdevsw *
-dev_refthread(struct cdev *dev)
+dev_refthread(struct cdev *dev, int *ref)
{
struct cdevsw *csw;
struct cdev_priv *cdp;
mtx_assert(&devmtx, MA_NOTOWNED);
+ if ((dev->si_flags & SI_ETERNAL) != 0) {
+ *ref = 0;
+ return (dev->si_devsw);
+ }
dev_lock();
csw = dev->si_devsw;
if (csw != NULL) {
@@ -193,36 +197,59 @@ dev_refthread(struct cdev *dev)
csw = NULL;
}
dev_unlock();
+ *ref = 1;
return (csw);
}
struct cdevsw *
-devvn_refthread(struct vnode *vp, struct cdev **devp)
+devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref)
{
struct cdevsw *csw;
struct cdev_priv *cdp;
+ struct cdev *dev;
mtx_assert(&devmtx, MA_NOTOWNED);
+ if ((vp->v_vflag & VV_ETERNALDEV) != 0) {
+ dev = vp->v_rdev;
+ if (dev == NULL)
+ return (NULL);
+ KASSERT((dev->si_flags & SI_ETERNAL) != 0,
+ ("Not eternal cdev"));
+ *ref = 0;
+ csw = dev->si_devsw;
+ KASSERT(csw != NULL, ("Eternal cdev is destroyed"));
+ *devp = dev;
+ return (csw);
+ }
+
csw = NULL;
dev_lock();
- *devp = vp->v_rdev;
- if (*devp != NULL) {
- cdp = cdev2priv(*devp);
- if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) {
- csw = (*devp)->si_devsw;
- if (csw != NULL)
- (*devp)->si_threadcount++;
- }
+ dev = vp->v_rdev;
+ if (dev == NULL) {
+ dev_unlock();
+ return (NULL);
+ }
+ cdp = cdev2priv(dev);
+ if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) {
+ csw = dev->si_devsw;
+ if (csw != NULL)
+ dev->si_threadcount++;
}
dev_unlock();
+ if (csw != NULL) {
+ *devp = dev;
+ *ref = 1;
+ }
return (csw);
}
void
-dev_relthread(struct cdev *dev)
+dev_relthread(struct cdev *dev, int ref)
{
mtx_assert(&devmtx, MA_NOTOWNED);
+ if (!ref)
+ return;
dev_lock();
KASSERT(dev->si_threadcount > 0,
("%s threadcount is wrong", dev->si_name));
@@ -325,15 +352,15 @@ static int
giant_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_open(dev, oflags, devtype, td);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -341,15 +368,15 @@ static int
giant_fdopen(struct cdev *dev, int oflags, struct thread *td, struct file *fp)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_fdopen(dev, oflags, td, fp);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -357,15 +384,15 @@ static int
giant_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_close(dev, fflag, devtype, td);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -374,9 +401,10 @@ giant_strategy(struct bio *bp)
{
struct cdevsw *dsw;
struct cdev *dev;
+ int ref;
dev = bp->bio_dev;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL) {
biofinish(bp, NULL, ENXIO);
return;
@@ -384,22 +412,22 @@ giant_strategy(struct bio *bp)
mtx_lock(&Giant);
dsw->d_gianttrick->d_strategy(bp);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
}
static int
giant_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_ioctl(dev, cmd, data, fflag, td);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -407,15 +435,15 @@ static int
giant_read(struct cdev *dev, struct uio *uio, int ioflag)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_read(dev, uio, ioflag);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -423,15 +451,15 @@ static int
giant_write(struct cdev *dev, struct uio *uio, int ioflag)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_write(dev, uio, ioflag);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -439,15 +467,15 @@ static int
giant_poll(struct cdev *dev, int events, struct thread *td)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_poll(dev, events, td);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -455,15 +483,15 @@ static int
giant_kqfilter(struct cdev *dev, struct knote *kn)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_kqfilter(dev, kn);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -472,9 +500,9 @@ giant_mmap(struct cdev *dev, vm_offset_t
vm_memattr_t *memattr)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
@@ -484,7 +512,7 @@ giant_mmap(struct cdev *dev, vm_offset_t
else
retval = dsw->d_gianttrick->d_mmap(dev, offset, paddr, nprot);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -493,16 +521,16 @@ giant_mmap_single(struct cdev *dev, vm_o
vm_object_t *object, int nprot)
{
struct cdevsw *dsw;
- int retval;
+ int ref, retval;
- dsw = dev_refthread(dev);
+ dsw = dev_refthread(dev, &ref);
if (dsw == NULL)
return (ENXIO);
mtx_lock(&Giant);
retval = dsw->d_gianttrick->d_mmap_single(dev, offset, size, object,
nprot);
mtx_unlock(&Giant);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (retval);
}
@@ -682,6 +710,8 @@ make_dev_credv(int flags, struct cdev **
dev = newdev(devsw, unit, dev);
if (flags & MAKEDEV_REF)
dev_refl(dev);
+ if (flags & MAKEDEV_ETERNAL)
+ dev->si_flags |= SI_ETERNAL;
if (dev->si_flags & SI_CHEAPCLONE &&
dev->si_flags & SI_NAMED) {
/*
@@ -846,6 +876,9 @@ destroy_devl(struct cdev *dev)
mtx_assert(&devmtx, MA_OWNED);
KASSERT(dev->si_flags & SI_NAMED,
("WARNING: Driver mistake: destroy_dev on %d\n", dev2unit(dev)));
+ KASSERT((dev->si_flags & SI_ETERNAL) == 0,
+ ("WARNING: Driver mistake: destroy_dev on eternal %d\n",
+ dev2unit(dev)));
devfs_destroy(dev);
Modified: stable/8/sys/kern/tty.c
==============================================================================
--- stable/8/sys/kern/tty.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/kern/tty.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -1777,7 +1777,7 @@ ttyhook_register(struct tty **rtp, struc
struct cdev *dev;
struct cdevsw *cdp;
struct filedesc *fdp;
- int error;
+ int error, ref;
/* Validate the file descriptor. */
if ((fdp = p->p_fd) == NULL)
@@ -1803,7 +1803,7 @@ ttyhook_register(struct tty **rtp, struc
}
/* Make sure it is a TTY. */
- cdp = devvn_refthread(fp->f_vnode, &dev);
+ cdp = devvn_refthread(fp->f_vnode, &dev, &ref);
if (cdp == NULL) {
error = ENXIO;
goto done1;
@@ -1839,7 +1839,7 @@ ttyhook_register(struct tty **rtp, struc
th->th_rint = ttyhook_defrint;
done3: tty_unlock(tp);
-done2: dev_relthread(dev);
+done2: dev_relthread(dev, ref);
done1: fdrop(fp, curthread);
return (error);
}
Modified: stable/8/sys/kern/vfs_bio.c
==============================================================================
--- stable/8/sys/kern/vfs_bio.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/kern/vfs_bio.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -3195,6 +3195,7 @@ dev_strategy(struct cdev *dev, struct bu
{
struct cdevsw *csw;
struct bio *bip;
+ int ref;
if ((!bp->b_iocmd) || (bp->b_iocmd & (bp->b_iocmd - 1)))
panic("b_iocmd botch");
@@ -3216,7 +3217,7 @@ dev_strategy(struct cdev *dev, struct bu
KASSERT(dev->si_refcount > 0,
("dev_strategy on un-referenced struct cdev *(%s)",
devtoname(dev)));
- csw = dev_refthread(dev);
+ csw = dev_refthread(dev, &ref);
if (csw == NULL) {
g_destroy_bio(bip);
bp->b_error = ENXIO;
@@ -3225,7 +3226,7 @@ dev_strategy(struct cdev *dev, struct bu
return;
}
(*csw->d_strategy)(bip);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
}
/*
Modified: stable/8/sys/sys/conf.h
==============================================================================
--- stable/8/sys/sys/conf.h Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/sys/conf.h Sun Sep 5 14:27:55 2010 (r212229)
@@ -54,6 +54,7 @@ struct file;
struct cdev {
void *__si_reserved;
u_int si_flags;
+#define SI_ETERNAL 0x0001 /* never destroyed */
#define SI_ALIAS 0x0002 /* carrier of alias name */
#define SI_NAMED 0x0004 /* make_dev{_alias} has been called */
#define SI_CHEAPCLONE 0x0008 /* can be removed_dev'ed when vnode reclaims */
@@ -258,9 +259,9 @@ int destroy_dev_sched(struct cdev *dev);
int destroy_dev_sched_cb(struct cdev *dev, void (*cb)(void *), void *arg);
void destroy_dev_drain(struct cdevsw *csw);
void drain_dev_clone_events(void);
-struct cdevsw *dev_refthread(struct cdev *_dev);
-struct cdevsw *devvn_refthread(struct vnode *vp, struct cdev **devp);
-void dev_relthread(struct cdev *_dev);
+struct cdevsw *dev_refthread(struct cdev *_dev, int *_ref);
+struct cdevsw *devvn_refthread(struct vnode *vp, struct cdev **devp, int *_ref);
+void dev_relthread(struct cdev *_dev, int _ref);
void dev_depends(struct cdev *_pdev, struct cdev *_cdev);
void dev_ref(struct cdev *dev);
void dev_refl(struct cdev *dev);
@@ -271,10 +272,11 @@ struct cdev *make_dev(struct cdevsw *_de
struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit,
struct ucred *_cr, uid_t _uid, gid_t _gid, int _perms,
const char *_fmt, ...) __printflike(7, 8);
-#define MAKEDEV_REF 0x1
-#define MAKEDEV_WHTOUT 0x2
-#define MAKEDEV_NOWAIT 0x4
-#define MAKEDEV_WAITOK 0x8
+#define MAKEDEV_REF 0x01
+#define MAKEDEV_WHTOUT 0x02
+#define MAKEDEV_NOWAIT 0x04
+#define MAKEDEV_WAITOK 0x08
+#define MAKEDEV_ETERNAL 0x10
struct cdev *make_dev_credf(int _flags,
struct cdevsw *_devsw, int _unit,
struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode,
@@ -288,6 +290,12 @@ void dev_lock(void);
void dev_unlock(void);
void setconf(void);
+#ifdef KLD_MODULE
+#define MAKEDEV_ETERNAL_KLD 0
+#else
+#define MAKEDEV_ETERNAL_KLD MAKEDEV_ETERNAL
+#endif
+
#define dev2unit(d) ((d)->si_drv0)
typedef void (*cdevpriv_dtr_t)(void *data);
Modified: stable/8/sys/sys/vnode.h
==============================================================================
--- stable/8/sys/sys/vnode.h Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/sys/vnode.h Sun Sep 5 14:27:55 2010 (r212229)
@@ -243,6 +243,7 @@ struct xvnode {
#define VV_ROOT 0x0001 /* root of its filesystem */
#define VV_ISTTY 0x0002 /* vnode represents a tty */
#define VV_NOSYNC 0x0004 /* unlinked, stop syncing */
+#define VV_ETERNALDEV 0x0008 /* device that is never destroyed */
#define VV_CACHEDLABEL 0x0010 /* Vnode has valid cached MAC label */
#define VV_TEXT 0x0020 /* vnode is a pure text prototype */
#define VV_COPYONWRITE 0x0040 /* vnode is doing copy-on-write */
Modified: stable/8/sys/vm/device_pager.c
==============================================================================
--- stable/8/sys/vm/device_pager.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/vm/device_pager.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -119,6 +119,7 @@ dev_pager_alloc(void *handle, vm_ooffset
vm_offset_t off;
vm_memattr_t dummy;
struct cdevsw *csw;
+ int ref;
/*
* Offset should be page aligned.
@@ -133,7 +134,7 @@ dev_pager_alloc(void *handle, vm_ooffset
* Make sure this device can be mapped.
*/
dev = handle;
- csw = dev_refthread(dev);
+ csw = dev_refthread(dev, &ref);
if (csw == NULL)
return (NULL);
@@ -146,7 +147,7 @@ dev_pager_alloc(void *handle, vm_ooffset
npages = OFF_TO_IDX(size);
for (off = foff; npages--; off += PAGE_SIZE)
if (dev_mmap(csw, dev, off, &paddr, (int)prot, &dummy) != 0) {
- dev_relthread(dev);
+ dev_relthread(dev, ref);
return (NULL);
}
@@ -188,7 +189,7 @@ dev_pager_alloc(void *handle, vm_ooffset
object->size = pindex;
}
mtx_unlock(&dev_pager_mtx);
- dev_relthread(dev);
+ dev_relthread(dev, ref);
vm_object_deallocate(object1);
return (object);
}
@@ -225,7 +226,7 @@ dev_pager_getpages(object, m, count, req
vm_page_t m_paddr, page;
vm_memattr_t memattr;
struct cdev *dev;
- int i, ret;
+ int i, ref, ret;
struct cdevsw *csw;
struct thread *td;
struct file *fpop;
@@ -236,7 +237,7 @@ dev_pager_getpages(object, m, count, req
offset = page->pindex;
memattr = object->memattr;
VM_OBJECT_UNLOCK(object);
- csw = dev_refthread(dev);
+ csw = dev_refthread(dev, &ref);
if (csw == NULL)
panic("dev_pager_getpage: no cdevsw");
td = curthread;
@@ -246,7 +247,7 @@ dev_pager_getpages(object, m, count, req
PROT_READ, &memattr);
KASSERT(ret == 0, ("dev_pager_getpage: map function returns error"));
td->td_fpop = fpop;
- dev_relthread(dev);
+ dev_relthread(dev, ref);
/* If "paddr" is a real page, perform a sanity check on "memattr". */
if ((m_paddr = vm_phys_paddr_to_vm_page(paddr)) != NULL &&
pmap_page_get_memattr(m_paddr) != memattr) {
Modified: stable/8/sys/vm/vm_mmap.c
==============================================================================
--- stable/8/sys/vm/vm_mmap.c Sun Sep 5 14:20:34 2010 (r212228)
+++ stable/8/sys/vm/vm_mmap.c Sun Sep 5 14:27:55 2010 (r212229)
@@ -1243,15 +1243,15 @@ vm_mmap_cdev(struct thread *td, vm_size_
{
vm_object_t obj;
struct cdevsw *dsw;
- int error, flags;
+ int error, flags, ref;
flags = *flagsp;
- dsw = dev_refthread(cdev);
+ dsw = dev_refthread(cdev, &ref);
if (dsw == NULL)
return (ENXIO);
if (dsw->d_flags & D_MMAP_ANON) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
*maxprotp = VM_PROT_ALL;
*flagsp |= MAP_ANON;
return (0);
@@ -1261,11 +1261,11 @@ vm_mmap_cdev(struct thread *td, vm_size_
*/
if ((*maxprotp & VM_PROT_WRITE) == 0 &&
(prot & PROT_WRITE) != 0) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
return (EACCES);
}
if (flags & (MAP_PRIVATE|MAP_COPY)) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
return (EINVAL);
}
/*
@@ -1275,7 +1275,7 @@ vm_mmap_cdev(struct thread *td, vm_size_
#ifdef MAC_XXX
error = mac_cdev_check_mmap(td->td_ucred, cdev, prot);
if (error != 0) {
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
return (error);
}
#endif
@@ -1289,7 +1289,7 @@ vm_mmap_cdev(struct thread *td, vm_size_
* XXX assumes VM_PROT_* == PROT_*
*/
error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot);
- dev_relthread(cdev);
+ dev_relthread(cdev, ref);
if (error != ENODEV)
return (error);
obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff,
More information about the svn-src-stable-8
mailing list