diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2013-03-30 06:32:26 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2013-03-30 06:32:26 +0000 |
commit | e81aee4ff1f613b05626bc1aed55232335030d62 (patch) | |
tree | 942f150344e657e20c283d341796570678104b71 /sys/kern/vfs_vnops.c | |
parent | 4f7a98323dff19295cc69dbe376897b27932d7cc (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.c | 7 |
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); } |