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 */ |