diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2014-04-12 14:18:12 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2014-04-12 14:18:12 +0000 |
commit | 90aedac78fd30f5b80b74898e508d1bd30fb6a1b (patch) | |
tree | b6da02407407f1ce082887ec86f74406092158ab /sys | |
parent | dd7da444383d73840b5a2c1b75e957ddbd04cd8f (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.c | 57 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 25 | ||||
-rw-r--r-- | sys/sys/filedesc.h | 4 |
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); |