diff options
Diffstat (limited to 'net/core/scm.c')
| -rw-r--r-- | net/core/scm.c | 24 | 
1 files changed, 21 insertions, 3 deletions
diff --git a/net/core/scm.c b/net/core/scm.c index f73c44b17dd..1e17949c12c 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -77,6 +77,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)  		if (!fpl)  			return -ENOMEM;  		*fplp = fpl; +		INIT_LIST_HEAD(&fpl->list);  		fpl->count = 0;  	}  	fpp = &fpl->fp[fpl->count]; @@ -108,9 +109,25 @@ void __scm_destroy(struct scm_cookie *scm)  	if (fpl) {  		scm->fp = NULL; -		for (i=fpl->count-1; i>=0; i--) -			fput(fpl->fp[i]); -		kfree(fpl); +		if (current->scm_work_list) { +			list_add_tail(&fpl->list, current->scm_work_list); +		} else { +			LIST_HEAD(work_list); + +			current->scm_work_list = &work_list; + +			list_add(&fpl->list, &work_list); +			while (!list_empty(&work_list)) { +				fpl = list_first_entry(&work_list, struct scm_fp_list, list); + +				list_del(&fpl->list); +				for (i=fpl->count-1; i>=0; i--) +					fput(fpl->fp[i]); +				kfree(fpl); +			} + +			current->scm_work_list = NULL; +		}  	}  } @@ -286,6 +303,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)  	new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);  	if (new_fpl) { +		INIT_LIST_HEAD(&new_fpl->list);  		for (i=fpl->count-1; i>=0; i--)  			get_file(fpl->fp[i]);  		memcpy(new_fpl, fpl, sizeof(*fpl));  |