fdgrowtable() no longer drops the filedesc lock so it is enough to

retry finding free file descriptor only once after fdgrowtable().

Spotted by:	pluknet
MFC after:	1 month
This commit is contained in:
Pawel Jakub Dawidek 2012-06-11 22:05:26 +00:00
parent efab609272
commit 039dc89f0d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=236935

View File

@ -1478,29 +1478,33 @@ fdalloc(struct thread *td, int minfd, int *result)
/*
* Search the bitmap for a free descriptor. If none is found, try
* to grow the file table. Keep at it until we either get a file
* descriptor or run into process or system limits; fdgrowtable()
* may drop the filedesc lock, so we're in a race.
* descriptor or run into process or system limits.
*/
for (;;) {
fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
if (fd >= maxfd)
return (EMFILE);
if (fd < fdp->fd_nfiles)
break;
fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
if (fd >= maxfd)
return (EMFILE);
if (fd >= fdp->fd_nfiles) {
#ifdef RACCT
PROC_LOCK(p);
error = racct_set(p, RACCT_NOFILE, min(fdp->fd_nfiles * 2, maxfd));
error = racct_set(p, RACCT_NOFILE,
min(fdp->fd_nfiles * 2, maxfd));
PROC_UNLOCK(p);
if (error != 0)
return (EMFILE);
#endif
fdgrowtable(fdp, min(fdp->fd_nfiles * 2, maxfd));
/* Retry... */
fd = fd_first_free(fdp, minfd, fdp->fd_nfiles);
if (fd >= maxfd)
return (EMFILE);
}
/*
* Perform some sanity checks, then mark the file descriptor as
* used and return it to the caller.
*/
KASSERT((unsigned int)fd < min(maxfd, fdp->fd_nfiles),
("invalid descriptor %d", fd));
KASSERT(!fdisused(fdp, fd),
("fd_first_free() returned non-free descriptor"));
KASSERT(fdp->fd_ofiles[fd] == NULL, ("file descriptor isn't free"));