| 202 | } |
| 203 | |
| 204 | struct cdevsw * |
| 205 | devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref) |
| 206 | { |
| 207 | struct cdevsw *csw; |
| 208 | struct cdev_priv *cdp; |
| 209 | struct cdev *dev; |
| 210 | |
| 211 | dev_lock_assert_unlocked(); |
| 212 | if ((vp->v_vflag & VV_ETERNALDEV) != 0) { |
| 213 | dev = vp->v_rdev; |
| 214 | if (dev == NULL) |
| 215 | return (NULL); |
| 216 | KASSERT((dev->si_flags & SI_ETERNAL) != 0, |
| 217 | ("Not eternal cdev")); |
| 218 | *ref = 0; |
| 219 | csw = dev->si_devsw; |
| 220 | KASSERT(csw != NULL, ("Eternal cdev is destroyed")); |
| 221 | *devp = dev; |
| 222 | return (csw); |
| 223 | } |
| 224 | |
| 225 | csw = NULL; |
| 226 | VI_LOCK(vp); |
| 227 | dev = vp->v_rdev; |
| 228 | if (dev == NULL) { |
| 229 | VI_UNLOCK(vp); |
| 230 | return (NULL); |
| 231 | } |
| 232 | cdp = cdev2priv(dev); |
| 233 | mtx_lock(&cdp->cdp_threadlock); |
| 234 | if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) { |
| 235 | csw = dev->si_devsw; |
| 236 | if (csw != NULL) |
| 237 | atomic_add_long(&dev->si_threadcount, 1); |
| 238 | } |
| 239 | mtx_unlock(&cdp->cdp_threadlock); |
| 240 | VI_UNLOCK(vp); |
| 241 | if (csw != NULL) { |
| 242 | *devp = dev; |
| 243 | *ref = 1; |
| 244 | } |
| 245 | return (csw); |
| 246 | } |
| 247 | |
| 248 | void |
| 249 | dev_relthread(struct cdev *dev, int ref) |
no test coverage detected