diff options
| -rw-r--r-- | include/net/request_sock.h | 18 | ||||
| -rw-r--r-- | net/core/request_sock.c | 35 |
2 files changed, 36 insertions, 17 deletions
diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 7aed02ce2b65..cff4608179c1 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h | |||
| @@ -124,23 +124,7 @@ struct request_sock_queue { | |||
| 124 | extern int reqsk_queue_alloc(struct request_sock_queue *queue, | 124 | extern int reqsk_queue_alloc(struct request_sock_queue *queue, |
| 125 | unsigned int nr_table_entries); | 125 | unsigned int nr_table_entries); |
| 126 | 126 | ||
| 127 | static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue) | 127 | extern void __reqsk_queue_destroy(struct request_sock_queue *queue); |
| 128 | { | ||
| 129 | struct listen_sock *lopt; | ||
| 130 | |||
| 131 | write_lock_bh(&queue->syn_wait_lock); | ||
| 132 | lopt = queue->listen_opt; | ||
| 133 | queue->listen_opt = NULL; | ||
| 134 | write_unlock_bh(&queue->syn_wait_lock); | ||
| 135 | |||
| 136 | return lopt; | ||
| 137 | } | ||
| 138 | |||
| 139 | static inline void __reqsk_queue_destroy(struct request_sock_queue *queue) | ||
| 140 | { | ||
| 141 | kfree(reqsk_queue_yank_listen_sk(queue)); | ||
| 142 | } | ||
| 143 | |||
| 144 | extern void reqsk_queue_destroy(struct request_sock_queue *queue); | 128 | extern void reqsk_queue_destroy(struct request_sock_queue *queue); |
| 145 | 129 | ||
| 146 | static inline struct request_sock * | 130 | static inline struct request_sock * |
diff --git a/net/core/request_sock.c b/net/core/request_sock.c index 5f0818d815e6..45aed75cb571 100644 --- a/net/core/request_sock.c +++ b/net/core/request_sock.c | |||
| @@ -71,6 +71,41 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, | |||
| 71 | 71 | ||
| 72 | EXPORT_SYMBOL(reqsk_queue_alloc); | 72 | EXPORT_SYMBOL(reqsk_queue_alloc); |
| 73 | 73 | ||
| 74 | void __reqsk_queue_destroy(struct request_sock_queue *queue) | ||
| 75 | { | ||
| 76 | struct listen_sock *lopt; | ||
| 77 | size_t lopt_size; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * this is an error recovery path only | ||
| 81 | * no locking needed and the lopt is not NULL | ||
| 82 | */ | ||
| 83 | |||
| 84 | lopt = queue->listen_opt; | ||
| 85 | lopt_size = sizeof(struct listen_sock) + | ||
| 86 | lopt->nr_table_entries * sizeof(struct request_sock *); | ||
| 87 | |||
| 88 | if (lopt_size > PAGE_SIZE) | ||
| 89 | vfree(lopt); | ||
| 90 | else | ||
| 91 | kfree(lopt); | ||
| 92 | } | ||
| 93 | |||
| 94 | EXPORT_SYMBOL(__reqsk_queue_destroy); | ||
| 95 | |||
| 96 | static inline struct listen_sock *reqsk_queue_yank_listen_sk( | ||
| 97 | struct request_sock_queue *queue) | ||
| 98 | { | ||
| 99 | struct listen_sock *lopt; | ||
| 100 | |||
| 101 | write_lock_bh(&queue->syn_wait_lock); | ||
| 102 | lopt = queue->listen_opt; | ||
| 103 | queue->listen_opt = NULL; | ||
| 104 | write_unlock_bh(&queue->syn_wait_lock); | ||
| 105 | |||
| 106 | return lopt; | ||
| 107 | } | ||
| 108 | |||
| 74 | void reqsk_queue_destroy(struct request_sock_queue *queue) | 109 | void reqsk_queue_destroy(struct request_sock_queue *queue) |
| 75 | { | 110 | { |
| 76 | /* make all the listen_opt local to us */ | 111 | /* make all the listen_opt local to us */ |
