Index: kern/kern_descrip.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.279.2.10 diff -u -r1.279.2.10 kern_descrip.c --- kern/kern_descrip.c 12 Jan 2007 16:21:28 -0000 1.279.2.10 +++ kern/kern_descrip.c 8 May 2007 08:42:30 -0000 @@ -666,7 +666,9 @@ * bad file descriptor. Userland should do its own locking to * avoid this case. */ - if (fdp->fd_ofiles[old] != fp) { + if (fdp->fd_ofiles[old] != fp || + (fdp->fd_ofileflags[old] & UF_OPENING) != 0 || + (fdp->fd_ofileflags[new] & UF_OPENING) != 0) { /* we've allocated a descriptor which we won't use */ if (fdp->fd_ofiles[new] == NULL) fdunused(fdp, new); @@ -983,7 +985,8 @@ FILEDESC_LOCK(fdp); if ((unsigned)fd >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[fd]) == NULL) { + (fp = fdp->fd_ofiles[fd]) == NULL || + (fdp->fd_ofileflags[fd] & UF_OPENING) != 0) { FILEDESC_UNLOCK(fdp); return (EBADF); } @@ -1509,7 +1512,8 @@ newfdp->fd_freefile = -1; for (i = 0; i <= fdp->fd_lastfile; ++i) { if (fdisused(fdp, i) && - fdp->fd_ofiles[i]->f_type != DTYPE_KQUEUE) { + fdp->fd_ofiles[i]->f_type != DTYPE_KQUEUE && + (fdp->fd_ofileflags[i] & UF_OPENING) == 0) { newfdp->fd_ofiles[i] = fdp->fd_ofiles[i]; newfdp->fd_ofileflags[i] = fdp->fd_ofileflags[i]; fhold(newfdp->fd_ofiles[i]); Index: kern/vfs_syscalls.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.392.2.18 diff -u -r1.392.2.18 vfs_syscalls.c --- kern/vfs_syscalls.c 23 Apr 2007 18:08:59 -0000 1.392.2.18 +++ kern/vfs_syscalls.c 8 May 2007 08:42:30 -0000 @@ -1004,7 +1004,19 @@ cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); td->td_dupfd = -1; /* XXX check for fdopen */ + FILEDESC_LOCK(fdp); + if (fp != fdp->fd_ofiles[indx]) { + FILEDESC_UNLOCK(fdp); + fdrop(fp, td); + td->td_retval[0] = indx; + return (0); + } + fdp->fd_ofileflags[indx] |= UF_OPENING; + FILEDESC_UNLOCK(fdp); error = vn_open(&nd, &flags, cmode, indx); + FILEDESC_LOCK(fdp); + fdp->fd_ofileflags[indx] &= ~UF_OPENING; + FILEDESC_UNLOCK(fdp); if (error) { /* * If the vn_open replaced the method vector, something Index: sys/filedesc.h =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sys/filedesc.h,v retrieving revision 1.72.2.1 diff -u -r1.72.2.1 filedesc.h --- sys/filedesc.h 9 Oct 2005 03:13:49 -0000 1.72.2.1 +++ sys/filedesc.h 8 May 2007 08:42:30 -0000 @@ -92,6 +92,7 @@ * Per-process open flags. */ #define UF_EXCLOSE 0x01 /* auto-close on exec */ +#define UF_OPENING 0x02 /* file is being opened */ #ifdef _KERNEL