summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2014-04-12 14:18:12 +0000
committerMarc Espie <espie@cvs.openbsd.org>2014-04-12 14:18:12 +0000
commit90aedac78fd30f5b80b74898e508d1bd30fb6a1b (patch)
treeb6da02407407f1ce082887ec86f74406092158ab /sys
parentdd7da444383d73840b5a2c1b75e957ddbd04cd8f (diff)
revert falloc change, as it causes all new processes to get stuck after a while
(race condition ?) problem noticed by me, aja, sthen, brynet, rpe. vanishing after this revert, okay aja@, sthen@ tedu, you probably want to look into re-checking the fcreate/fpublish addition first, then if it's stable, see about tweaking doopenat ?
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_descrip.c57
-rw-r--r--sys/kern/vfs_syscalls.c25
-rw-r--r--sys/sys/filedesc.h4
3 files changed, 21 insertions, 65 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c1b5ee0f28b..ab36785730d 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_descrip.c,v 1.106 2014/03/30 21:54:48 guenther Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.107 2014/04/12 14:18:11 espie Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
@@ -820,28 +820,20 @@ fdexpand(struct proc *p)
int
falloc(struct proc *p, struct file **resultfp, int *resultfd)
{
- int error;
-
- if ((error = fcreate(p, resultfp)))
- return (error);
- if ((error = fpublish(p, *resultfp, resultfd)))
- closef(*resultfp, p);
- return (error);
-}
-
-int
-fcreate(struct proc *p, struct file **resultfp)
-{
- struct filedesc *fdp = p->p_fd;
struct file *fp, *fq;
- int lim;
-
- fdpassertlocked(fdp);
- lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
- if (fdp->fd_openfd >= lim)
- return (EMFILE);
+ int error, i;
+ fdpassertlocked(p->p_fd);
+restart:
+ if ((error = fdalloc(p, 0, &i)) != 0) {
+ if (error == ENOSPC) {
+ fdexpand(p);
+ goto restart;
+ }
+ return (error);
+ }
if (nfiles >= maxfiles) {
+ fd_unused(p->p_fd, i);
tablefull("file");
return (ENFILE);
}
@@ -851,7 +843,6 @@ fcreate(struct proc *p, struct file **resultfp)
* of open files at that point, otherwise put it at the front of
* the list of open files.
*/
- fdp->fd_openfd++;
nfiles++;
fp = pool_get(&file_pool, PR_WAITOK|PR_ZERO);
fp->f_iflags = FIF_LARVAL;
@@ -860,35 +851,15 @@ fcreate(struct proc *p, struct file **resultfp)
} else {
LIST_INSERT_HEAD(&filehead, fp, f_list);
}
+ p->p_fd->fd_ofiles[i] = fp;
fp->f_count = 1;
fp->f_cred = p->p_ucred;
crhold(fp->f_cred);
if (resultfp)
*resultfp = fp;
- FREF(fp);
- return (0);
-}
-
-int
-fpublish(struct proc *p, struct file *fp, int *resultfd)
-{
- struct filedesc *fdp = p->p_fd;
- int i, error;
-
- fdpassertlocked(fdp);
- fdp->fd_openfd--; /* undo previous increase by fcreate */
-restart:
- if ((error = fdalloc(p, 0, &i)) != 0) {
- if (error == ENOSPC) {
- fdexpand(p);
- goto restart;
- }
- return (error);
- }
-
- fdp->fd_ofiles[i] = fp;
if (resultfd)
*resultfd = i;
+ FREF(fp);
return (0);
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 527251ed44d..8b2113fb849 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.204 2014/03/30 21:54:48 guenther Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.205 2014/04/12 14:18:11 espie Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -841,15 +841,17 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
struct vnode *vp;
struct vattr vattr;
int flags, cmode;
- int type, indx, error, fpuberr, localtrunc = 0;
+ int type, indx, error, localtrunc = 0;
struct flock lf;
struct nameidata nd;
fdplock(fdp);
- if ((error = fcreate(p, &fp)) != 0)
+ if ((error = falloc(p, &fp, &indx)) != 0)
goto out;
flags = FFLAGS(oflags);
+ if (flags & O_CLOEXEC)
+ fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
NDINITAT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fd, path, p);
@@ -858,22 +860,7 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
localtrunc = 1;
flags &= ~O_TRUNC; /* Must do truncate ourselves */
}
-
- fdpunlock(fdp);
- error = vn_open(&nd, flags, cmode);
- fdplock(fdp);
-
- if ((fpuberr = fpublish(p, fp, &indx)) != 0) {
- /* should never happen; just in case */
- if (error == 0)
- vn_close(nd.ni_vp, flags & FMASK, p->p_ucred, p);
- closef(fp, p);
- error = fpuberr;
- goto out;
- }
- if (flags & O_CLOEXEC)
- fdp->fd_ofileflags[indx] |= UF_EXCLOSE;
- if (error != 0) {
+ if ((error = vn_open(&nd, flags, cmode)) != 0) {
if (error == ENODEV &&
p->p_dupfd >= 0 && /* XXX from fdopen */
(error =
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 8a61e41ff1c..452c7a41c0d 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: filedesc.h,v 1.26 2014/03/08 22:54:30 tedu Exp $ */
+/* $OpenBSD: filedesc.h,v 1.27 2014/04/12 14:18:11 espie Exp $ */
/* $NetBSD: filedesc.h,v 1.14 1996/04/09 20:55:28 cgd Exp $ */
/*
@@ -125,8 +125,6 @@ int dupfdopen(struct filedesc *, int, int, int);
int fdalloc(struct proc *p, int want, int *result);
void fdexpand(struct proc *);
int falloc(struct proc *p, struct file **resultfp, int *resultfd);
-int fcreate(struct proc *p, struct file **resultfp);
-int fpublish(struct proc *p, struct file *fp, int *resultfd);
struct filedesc *fdinit(struct proc *p);
struct filedesc *fdshare(struct proc *p);
struct filedesc *fdcopy(struct proc *p);