aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/deadfs/dead_vnops.c10
-rw-r--r--sys/fs/devfs/devfs_int.h1
-rw-r--r--sys/fs/devfs/devfs_vnops.c17
3 files changed, 20 insertions, 8 deletions
diff --git a/sys/fs/deadfs/dead_vnops.c b/sys/fs/deadfs/dead_vnops.c
index 296cf058f8c9..137c86b65058 100644
--- a/sys/fs/deadfs/dead_vnops.c
+++ b/sys/fs/deadfs/dead_vnops.c
@@ -122,18 +122,18 @@ dead_read(struct vop_read_args *ap)
{
/*
- * Return EOF for tty devices, EIO for others
+ * Return EOF for tty devices, ENXIO for others
*/
- if ((ap->a_vp->v_vflag & VV_ISTTY) == 0)
- return (EIO);
- return (0);
+ if (ap->a_vp->v_vflag & VV_ISTTY)
+ return (0);
+ return (ENXIO);
}
int
dead_write(struct vop_write_args *ap)
{
- return (EIO);
+ return (ENXIO);
}
int
diff --git a/sys/fs/devfs/devfs_int.h b/sys/fs/devfs/devfs_int.h
index 916297425b53..9fa75c0e90ad 100644
--- a/sys/fs/devfs/devfs_int.h
+++ b/sys/fs/devfs/devfs_int.h
@@ -67,6 +67,7 @@ struct cdev_priv {
void *cdp_dtr_cb_arg;
LIST_HEAD(, cdev_privdata) cdp_fdpriv;
+ u_int cdp_fdpriv_dtrc;
struct mtx cdp_threadlock;
};
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index caadf257b8ad..323f1e0fa961 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -200,14 +200,25 @@ devfs_foreach_cdevpriv(struct cdev *dev, int (*cb)(void *data, void *arg),
void
devfs_destroy_cdevpriv(struct cdev_privdata *p)
{
+ struct file *fp;
+ struct cdev_priv *cdp;
mtx_assert(&cdevpriv_mtx, MA_OWNED);
- KASSERT(p->cdpd_fp->f_cdevpriv == p,
- ("devfs_destoy_cdevpriv %p != %p", p->cdpd_fp->f_cdevpriv, p));
- p->cdpd_fp->f_cdevpriv = NULL;
+ fp = p->cdpd_fp;
+ KASSERT(fp->f_cdevpriv == p,
+ ("devfs_destoy_cdevpriv %p != %p", fp->f_cdevpriv, p));
+ cdp = cdev2priv((struct cdev *)fp->f_data);
+ cdp->cdp_fdpriv_dtrc++;
+ fp->f_cdevpriv = NULL;
LIST_REMOVE(p, cdpd_list);
mtx_unlock(&cdevpriv_mtx);
(p->cdpd_dtr)(p->cdpd_data);
+ mtx_lock(&cdevpriv_mtx);
+ MPASS(cdp->cdp_fdpriv_dtrc >= 1);
+ cdp->cdp_fdpriv_dtrc--;
+ if (cdp->cdp_fdpriv_dtrc == 0)
+ wakeup(&cdp->cdp_fdpriv_dtrc);
+ mtx_unlock(&cdevpriv_mtx);
free(p, M_CDEVPDATA);
}