diff options
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 2 | ||||
-rw-r--r-- | net/unix/garbage.c | 13 |
2 files changed, 12 insertions, 3 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5aaf23e43f1d..92f52abd3515 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1351,6 +1351,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1351 | 1351 | ||
1352 | if (NULL == siocb->scm) | 1352 | if (NULL == siocb->scm) |
1353 | siocb->scm = &tmp_scm; | 1353 | siocb->scm = &tmp_scm; |
1354 | wait_for_unix_gc(); | ||
1354 | err = scm_send(sock, msg, siocb->scm); | 1355 | err = scm_send(sock, msg, siocb->scm); |
1355 | if (err < 0) | 1356 | if (err < 0) |
1356 | return err; | 1357 | return err; |
@@ -1501,6 +1502,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1501 | 1502 | ||
1502 | if (NULL == siocb->scm) | 1503 | if (NULL == siocb->scm) |
1503 | siocb->scm = &tmp_scm; | 1504 | siocb->scm = &tmp_scm; |
1505 | wait_for_unix_gc(); | ||
1504 | err = scm_send(sock, msg, siocb->scm); | 1506 | err = scm_send(sock, msg, siocb->scm); |
1505 | if (err < 0) | 1507 | if (err < 0) |
1506 | return err; | 1508 | return err; |
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 5a0061d6b9bc..19c17e4a0c8b 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #include <linux/file.h> | 80 | #include <linux/file.h> |
81 | #include <linux/proc_fs.h> | 81 | #include <linux/proc_fs.h> |
82 | #include <linux/mutex.h> | 82 | #include <linux/mutex.h> |
83 | #include <linux/wait.h> | ||
83 | 84 | ||
84 | #include <net/sock.h> | 85 | #include <net/sock.h> |
85 | #include <net/af_unix.h> | 86 | #include <net/af_unix.h> |
@@ -91,6 +92,7 @@ | |||
91 | static LIST_HEAD(gc_inflight_list); | 92 | static LIST_HEAD(gc_inflight_list); |
92 | static LIST_HEAD(gc_candidates); | 93 | static LIST_HEAD(gc_candidates); |
93 | static DEFINE_SPINLOCK(unix_gc_lock); | 94 | static DEFINE_SPINLOCK(unix_gc_lock); |
95 | static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); | ||
94 | 96 | ||
95 | unsigned int unix_tot_inflight; | 97 | unsigned int unix_tot_inflight; |
96 | 98 | ||
@@ -266,12 +268,16 @@ static void inc_inflight_move_tail(struct unix_sock *u) | |||
266 | list_move_tail(&u->link, &gc_candidates); | 268 | list_move_tail(&u->link, &gc_candidates); |
267 | } | 269 | } |
268 | 270 | ||
269 | /* The external entry point: unix_gc() */ | 271 | static bool gc_in_progress = false; |
270 | 272 | ||
271 | void unix_gc(void) | 273 | void wait_for_unix_gc(void) |
272 | { | 274 | { |
273 | static bool gc_in_progress = false; | 275 | wait_event(unix_gc_wait, gc_in_progress == false); |
276 | } | ||
274 | 277 | ||
278 | /* The external entry point: unix_gc() */ | ||
279 | void unix_gc(void) | ||
280 | { | ||
275 | struct unix_sock *u; | 281 | struct unix_sock *u; |
276 | struct unix_sock *next; | 282 | struct unix_sock *next; |
277 | struct sk_buff_head hitlist; | 283 | struct sk_buff_head hitlist; |
@@ -376,6 +382,7 @@ void unix_gc(void) | |||
376 | /* All candidates should have been detached by now. */ | 382 | /* All candidates should have been detached by now. */ |
377 | BUG_ON(!list_empty(&gc_candidates)); | 383 | BUG_ON(!list_empty(&gc_candidates)); |
378 | gc_in_progress = false; | 384 | gc_in_progress = false; |
385 | wake_up(&unix_gc_wait); | ||
379 | 386 | ||
380 | out: | 387 | out: |
381 | spin_unlock(&unix_gc_lock); | 388 | spin_unlock(&unix_gc_lock); |