aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/scm.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/net/core/scm.c b/net/core/scm.c
index 10f5c65f6a47..ab242cc1acca 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
75 if (!fpl) 75 if (!fpl)
76 return -ENOMEM; 76 return -ENOMEM;
77 *fplp = fpl; 77 *fplp = fpl;
78 INIT_LIST_HEAD(&fpl->list);
78 fpl->count = 0; 79 fpl->count = 0;
79 } 80 }
80 fpp = &fpl->fp[fpl->count]; 81 fpp = &fpl->fp[fpl->count];
@@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm)
106 107
107 if (fpl) { 108 if (fpl) {
108 scm->fp = NULL; 109 scm->fp = NULL;
109 for (i=fpl->count-1; i>=0; i--) 110 if (current->scm_work_list) {
110 fput(fpl->fp[i]); 111 list_add_tail(&fpl->list, current->scm_work_list);
111 kfree(fpl); 112 } else {
113 LIST_HEAD(work_list);
114
115 current->scm_work_list = &work_list;
116
117 list_add(&fpl->list, &work_list);
118 while (!list_empty(&work_list)) {
119 fpl = list_first_entry(&work_list, struct scm_fp_list, list);
120
121 list_del(&fpl->list);
122 for (i=fpl->count-1; i>=0; i--)
123 fput(fpl->fp[i]);
124 kfree(fpl);
125 }
126
127 current->scm_work_list = NULL;
128 }
112 } 129 }
113} 130}
114 131
@@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
284 301
285 new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); 302 new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
286 if (new_fpl) { 303 if (new_fpl) {
304 INIT_LIST_HEAD(&new_fpl->list);
287 for (i=fpl->count-1; i>=0; i--) 305 for (i=fpl->count-1; i>=0; i--)
288 get_file(fpl->fp[i]); 306 get_file(fpl->fp[i]);
289 memcpy(new_fpl, fpl, sizeof(*fpl)); 307 memcpy(new_fpl, fpl, sizeof(*fpl));