summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2012-07-11 23:07:20 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2012-07-11 23:07:20 +0000
commit53be5ecb9959921ecc47ae107f13af875f61ca42 (patch)
tree88b6d74214b61c0ff0960dba8bb8a92a66452a7c /sys/kern/vfs_syscalls.c
parenteedb6cd713a1ad6e1021690fe7a8f927fa3f3f01 (diff)
Revert the blocked FIFO open fix, as there's either a race in the
ref-count handling under handling, or blambert@ is messing with my head
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index c6462898d5e..b8ccd2b94d6 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.186 2012/07/10 17:00:55 guenther Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.187 2012/07/11 23:07:19 guenther Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -856,14 +856,12 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
struct nameidata nd;
fdplock(fdp);
- if ((error = falloc(p, &fp, &indx)) != 0) {
- fdpunlock(fdp);
- return (error);
- }
+
+ if ((error = falloc(p, &fp, &indx)) != 0)
+ goto out;
flags = FFLAGS(oflags);
if (flags & O_CLOEXEC)
fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
- fdpunlock(fdp);
cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
NDINITAT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fd, path, p);
@@ -873,16 +871,19 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
flags &= ~O_TRUNC; /* Must do truncate ourselves */
}
if ((error = vn_open(&nd, flags, cmode)) != 0) {
- fdplock(fdp);
if (error == ENODEV &&
p->p_dupfd >= 0 && /* XXX from fdopen */
- (error = dupfdopen(p, indx, fp, flags)) == 0) {
+ (error =
+ dupfdopen(fdp, indx, p->p_dupfd, flags)) == 0) {
+ closef(fp, p);
*retval = indx;
goto out;
}
if (error == ERESTART)
error = EINTR;
- goto err;
+ fdremove(fdp, indx);
+ closef(fp, p);
+ goto out;
}
p->p_dupfd = 0;
vp = nd.ni_vp;
@@ -904,9 +905,10 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
VOP_UNLOCK(vp, 0, p);
error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type);
if (error) {
- /* FRELE will vn_close the file for us. */
- fdplock(fdp);
- goto err;
+ /* closef will vn_close the file for us. */
+ fdremove(fdp, indx);
+ closef(fp, p);
+ goto out;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
fp->f_flag |= FHASLOCK;
@@ -925,25 +927,17 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
}
if (error) {
VOP_UNLOCK(vp, 0, p);
- /* FRELE will close the file for us. */
- fdplock(fdp);
- goto err;
+ /* closef will close the file for us. */
+ fdremove(fdp, indx);
+ closef(fp, p);
+ goto out;
}
}
VOP_UNLOCK(vp, 0, p);
*retval = indx;
FILE_SET_MATURE(fp, p);
- return (0);
-
-err:
- /* only remove the fd if the file didn't change behind out back */
- if (fdp->fd_ofiles[indx] == fp) {
- fdremove(fdp, indx);
- FRELE(fp, p);
- }
out:
fdpunlock(fdp);
- FRELE(fp, p);
return (error);
}