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:
parent
614251e3b5
commit
5aae11ec2e
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user