We allocate an array of pointers to the global file table while

not holding the filelist_lock.  This means the filelist can change
size while allocating.  Detect this race and retry the allocation.
This commit is contained in:
alfred 2004-07-02 07:40:10 +00:00
parent 614251e3b5
commit 5aae11ec2e

View File

@ -1395,6 +1395,8 @@ unp_gc()
register struct socket *so;
struct file **extra_ref, **fpp;
int nunref, i;
int nfiles_snap;
int nfiles_slack = 20;
UNP_LOCK_ASSERT();
@ -1537,8 +1539,17 @@ unp_gc()
*
* 91/09/19, bsy@cs.cmu.edu
*/
extra_ref = malloc(nfiles * sizeof(struct file *), M_TEMP, M_WAITOK);
again:
nfiles_snap = nfiles + nfiles_slack; /* some slack */
extra_ref = malloc(nfiles_snap * sizeof(struct file *), M_TEMP,
M_WAITOK);
sx_slock(&filelist_lock);
if (nfiles_snap < nfiles) {
sx_sunlock(&filelist_lock);
free(extra_ref, M_TEMP);
nfiles_slack += 20;
goto again;
}
for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref;
fp != NULL; fp = nextfp) {
nextfp = LIST_NEXT(fp, f_list);