diff options
author | jhb <jhb@FreeBSD.org> | 2002-07-17 02:48:43 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2002-07-17 02:48:43 +0000 |
commit | 3af47b505779529ef058e22b9ae31366e60ffa70 (patch) | |
tree | 1eebff95653ad26595d2e12ca7b5bfdcdf4d355e /sys | |
parent | 0ae44e9908e1c97278867390b837a5157e346ccd (diff) | |
download | FreeBSD-src-3af47b505779529ef058e22b9ae31366e60ffa70.zip FreeBSD-src-3af47b505779529ef058e22b9ae31366e60ffa70.tar.gz |
Preallocate a struct file as the first thing in falloc() before we lock
the filelist_lock and check nfiles. This closes a race where we had to
unlock the filedesc to re-lock the filelist_lock.
Reported by: David Xu
Reviewed by: bde (mostly)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_descrip.c | 21 |
1 files changed, 5 insertions, 16 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index f030284..43a7e44 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1107,32 +1107,24 @@ falloc(td, resultfp, resultfd) register struct file *fp, *fq; int error, i; + fp = uma_zalloc(file_zone, M_WAITOK | M_ZERO); sx_xlock(&filelist_lock); if (nfiles >= maxfiles) { sx_xunlock(&filelist_lock); + uma_zfree(file_zone, fp); tablefull("file"); return (ENFILE); } nfiles++; - sx_xunlock(&filelist_lock); - /* - * Allocate a new file descriptor. - * If the process has file descriptor zero open, add to the list - * of open files at that point, otherwise put it at the front of - * the list of open files. - */ - fp = uma_zalloc(file_zone, M_WAITOK); - bzero(fp, sizeof(*fp)); /* - * wait until after malloc (which may have blocked) returns before - * allocating the slot, else a race might have shrunk it if we had - * allocated it before the malloc. + * If the process has file descriptor zero open, add the new file + * descriptor to the list of open files at that point, otherwise + * put it at the front of the list of open files. */ FILEDESC_LOCK(p->p_fd); if ((error = fdalloc(td, 0, &i))) { FILEDESC_UNLOCK(p->p_fd); - sx_xlock(&filelist_lock); nfiles--; sx_xunlock(&filelist_lock); uma_zfree(file_zone, fp); @@ -1144,9 +1136,6 @@ falloc(td, resultfp, resultfd) fp->f_cred = crhold(td->td_ucred); fp->f_ops = &badfileops; fp->f_seqcount = 1; - FILEDESC_UNLOCK(p->p_fd); - sx_xlock(&filelist_lock); - FILEDESC_LOCK(p->p_fd); if ((fq = p->p_fd->fd_ofiles[0])) { LIST_INSERT_AFTER(fq, fp, f_list); } else { |