summaryrefslogtreecommitdiffstats
path: root/sys/fs/devfs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/devfs')
-rw-r--r--sys/fs/devfs/devfs_vnops.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 47cc01c..dc39e67 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -154,6 +154,20 @@ devfs_allocv_drop_refs(int drop_dm_lock, struct devfs_mount *dmp,
return (not_found);
}
+static void
+devfs_insmntque_dtr(struct vnode *vp, void *arg)
+{
+ struct devfs_dirent *de;
+
+ de = (struct devfs_dirent *)arg;
+ mtx_lock(&devfs_de_interlock);
+ vp->v_data = NULL;
+ de->de_vnode = NULL;
+ mtx_unlock(&devfs_de_interlock);
+ vgone(vp);
+ vput(vp);
+}
+
/*
* devfs_allocv shall be entered with dmp->dm_lock held, and it drops
* it on return.
@@ -230,13 +244,16 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, stru
} else {
vp->v_type = VBAD;
}
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
mtx_lock(&devfs_de_interlock);
vp->v_data = de;
de->de_vnode = vp;
mtx_unlock(&devfs_de_interlock);
- sx_xunlock(&dmp->dm_lock);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
- sx_xlock(&dmp->dm_lock);
+ error = insmntque1(vp, mp, devfs_insmntque_dtr, de);
+ if (error != 0) {
+ (void) devfs_allocv_drop_refs(1, dmp, de);
+ return (error);
+ }
if (devfs_allocv_drop_refs(0, dmp, de)) {
vput(vp);
return (ENOENT);
OpenPOWER on IntegriCloud