Do a major cleanup of the file descriptor handling code in preparation for
authorMatthew Dillon <dillon@dragonflybsd.org>
Mon, 22 May 2006 21:21:26 +0000 (21:21 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Mon, 22 May 2006 21:21:26 +0000 (21:21 +0000)
commit259b8ea0142512f3fc5315c769effd4ff85db9b1
tree5be51cabed351d095a29c43d8e20364596650acf
parentd511d5d57ef5b40885eda2c87435ef70a6ef9bf6
Do a major cleanup of the file descriptor handling code in preparation for
making the descriptor table MPSAFE.  Introduce a new feature that allows a
file descriptor number to be reserved without having to assign a file
pointer to it.  This allows code such as open(), dup(), etc to reserve
descriptors to work with without having to worry about the related file
being ripped out from under them by another thread sharing the descriptor
table.

falloc() - This function allocates the file pointer and descriptor as
before, but does NOT associate the file pointer with the
descriptor.

Before this change another thread could access the file
pointer while the system call creating it was blocked,
before the system call had a chance to completely initialize
the file pointer.

The caller must call fsetfd() to assign or clear the
reserved descriptor.

fsetfd() - Is now responsible for associating a file pointer with a
previously reserved descriptor or clearing the reservation.

fdealloc() - This hack existed to deal with open/dup races against other
threads.  The above changes remove the possibility so this
routine has been deleted.

dup code - kern_dup() and dupfdopen() have been completely rewritten.
They are much cleaner and less obtuse now.  Additional race
conditions in the original code were also found and fixed.

funsetfd() - Now returns the file pointer that was cleared and takes
responsibility for adjusting fd_lastfile.

NOTE: fd_lastfile is inclusive of any reserved descriptors.

fdcopy() - While not yet MPSAFE, fdcopy now properly handles races
against other threads.

fdp->fd_lastfile -
This field was not being properly updated in certain failure
cases.  This commit fixes that.  Also, if all a process's
descriptors were closed this field was incorrectly left at
0 when it should have been set to -1.

fdp->fd_files - A number of code blocks were trying to optimize a for()
loop over all file descriptors by caching a pointer to
fd_files.  This is a problem because fd_files can be
reallocated if code within the loop blocks.  These loops
have been rewritten.
sys/kern/kern_checkpoint.c
sys/kern/kern_descrip.c
sys/kern/kern_event.c
sys/kern/sys_pipe.c
sys/kern/uipc_syscalls.c
sys/kern/uipc_usrreq.c
sys/kern/vfs_syscalls.c
sys/opencrypto/cryptodev.c
sys/sys/filedesc.h