Index: sys/filedesc.h =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/sys/filedesc.h,v retrieving revision 1.76 diff -u -r1.76 filedesc.h --- sys/filedesc.h 4 Apr 2007 09:11:34 -0000 1.76 +++ sys/filedesc.h 18 Apr 2007 03:40:05 -0000 @@ -89,6 +89,7 @@ * Per-process open flags. */ #define UF_EXCLOSE 0x01 /* auto-close on exec */ +#define UF_OPENING 0x02 /* file is being opened */ #ifdef _KERNEL Index: kern/kern_descrip.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.307 diff -u -r1.307 kern_descrip.c --- kern/kern_descrip.c 4 Apr 2007 09:11:32 -0000 1.307 +++ kern/kern_descrip.c 18 Apr 2007 03:40:05 -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); @@ -990,7 +992,8 @@ FILEDESC_XLOCK(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_XUNLOCK(fdp); return (EBADF); } @@ -1504,7 +1507,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.437 diff -u -r1.437 vfs_syscalls.c --- kern/vfs_syscalls.c 5 Apr 2007 21:10:53 -0000 1.437 +++ kern/vfs_syscalls.c 18 Apr 2007 03:40:05 -0000 @@ -984,7 +984,19 @@ cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td); td->td_dupfd = -1; /* XXX check for fdopen */ + FILEDESC_XLOCK(fdp); + if (fp != fdp->fd_ofiles[indx]) { + FILEDESC_XUNLOCK(fdp); + fdrop(fp, td); + td->td_retval[0] = indx; + return (0); + } + fdp->fd_ofileflags[indx] |= UF_OPENING; + FILEDESC_XUNLOCK(fdp); error = vn_open(&nd, &flags, cmode, indx); + FILEDESC_XLOCK(fdp); + fdp->fd_ofileflags[indx] &= ~UF_OPENING; + FILEDESC_XUNLOCK(fdp); if (error) { /* * If the vn_open replaced the method vector, something