summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-03-30 06:32:26 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-03-30 06:32:26 +0000
commite81aee4ff1f613b05626bc1aed55232335030d62 (patch)
tree942f150344e657e20c283d341796570678104b71 /sys/kern/vfs_vnops.c
parent4f7a98323dff19295cc69dbe376897b27932d7cc (diff)
vrele() is a tricky beast. it can sleep if the refcount hits zero,
leaving us with a free type function that isn't atomic. deal with this by erasing any reachable pointers to the vnode first, then free it. ok deraadt guenther
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r--sys/kern/vfs_vnops.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index b7927924bff..9d8ead6f30c 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_vnops.c,v 1.71 2012/07/11 12:39:20 guenther Exp $ */
+/* $OpenBSD: vfs_vnops.c,v 1.72 2013/03/30 06:32:25 tedu Exp $ */
/* $NetBSD: vfs_vnops.c,v 1.20 1996/02/04 02:18:41 christos Exp $ */
/*
@@ -482,10 +482,11 @@ vn_ioctl(struct file *fp, u_long com, caddr_t data, struct proc *p)
error = VOP_IOCTL(vp, com, data, fp->f_flag, p->p_ucred, p);
if (error == 0 && com == TIOCSCTTY) {
struct session *s = p->p_p->ps_session;
- if (s->s_ttyvp)
- vrele(s->s_ttyvp);
+ struct vnode *ovp = s->s_ttyvp;
s->s_ttyvp = vp;
vref(vp);
+ if (ovp)
+ vrele(ovp);
}
return (error);
}