diff options
Diffstat (limited to 'net')
73 files changed, 810 insertions, 562 deletions
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 798beac7f100..1e308f210928 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -178,27 +178,24 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
178 | break; | 178 | break; |
179 | case 's':{ | 179 | case 's':{ |
180 | char **sptr = va_arg(ap, char **); | 180 | char **sptr = va_arg(ap, char **); |
181 | int16_t len; | 181 | uint16_t len; |
182 | int size; | ||
183 | 182 | ||
184 | errcode = p9pdu_readf(pdu, proto_version, | 183 | errcode = p9pdu_readf(pdu, proto_version, |
185 | "w", &len); | 184 | "w", &len); |
186 | if (errcode) | 185 | if (errcode) |
187 | break; | 186 | break; |
188 | 187 | ||
189 | size = max_t(int16_t, len, 0); | 188 | *sptr = kmalloc(len + 1, GFP_KERNEL); |
190 | |||
191 | *sptr = kmalloc(size + 1, GFP_KERNEL); | ||
192 | if (*sptr == NULL) { | 189 | if (*sptr == NULL) { |
193 | errcode = -EFAULT; | 190 | errcode = -EFAULT; |
194 | break; | 191 | break; |
195 | } | 192 | } |
196 | if (pdu_read(pdu, *sptr, size)) { | 193 | if (pdu_read(pdu, *sptr, len)) { |
197 | errcode = -EFAULT; | 194 | errcode = -EFAULT; |
198 | kfree(*sptr); | 195 | kfree(*sptr); |
199 | *sptr = NULL; | 196 | *sptr = NULL; |
200 | } else | 197 | } else |
201 | (*sptr)[size] = 0; | 198 | (*sptr)[len] = 0; |
202 | } | 199 | } |
203 | break; | 200 | break; |
204 | case 'Q':{ | 201 | case 'Q':{ |
@@ -234,14 +231,14 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
234 | } | 231 | } |
235 | break; | 232 | break; |
236 | case 'D':{ | 233 | case 'D':{ |
237 | int32_t *count = va_arg(ap, int32_t *); | 234 | uint32_t *count = va_arg(ap, uint32_t *); |
238 | void **data = va_arg(ap, void **); | 235 | void **data = va_arg(ap, void **); |
239 | 236 | ||
240 | errcode = | 237 | errcode = |
241 | p9pdu_readf(pdu, proto_version, "d", count); | 238 | p9pdu_readf(pdu, proto_version, "d", count); |
242 | if (!errcode) { | 239 | if (!errcode) { |
243 | *count = | 240 | *count = |
244 | min_t(int32_t, *count, | 241 | min_t(uint32_t, *count, |
245 | pdu->size - pdu->offset); | 242 | pdu->size - pdu->offset); |
246 | *data = &pdu->sdata[pdu->offset]; | 243 | *data = &pdu->sdata[pdu->offset]; |
247 | } | 244 | } |
@@ -404,9 +401,10 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
404 | break; | 401 | break; |
405 | case 's':{ | 402 | case 's':{ |
406 | const char *sptr = va_arg(ap, const char *); | 403 | const char *sptr = va_arg(ap, const char *); |
407 | int16_t len = 0; | 404 | uint16_t len = 0; |
408 | if (sptr) | 405 | if (sptr) |
409 | len = min_t(int16_t, strlen(sptr), USHRT_MAX); | 406 | len = min_t(uint16_t, strlen(sptr), |
407 | USHRT_MAX); | ||
410 | 408 | ||
411 | errcode = p9pdu_writef(pdu, proto_version, | 409 | errcode = p9pdu_writef(pdu, proto_version, |
412 | "w", len); | 410 | "w", len); |
@@ -438,7 +436,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
438 | stbuf->n_gid, stbuf->n_muid); | 436 | stbuf->n_gid, stbuf->n_muid); |
439 | } break; | 437 | } break; |
440 | case 'D':{ | 438 | case 'D':{ |
441 | int32_t count = va_arg(ap, int32_t); | 439 | uint32_t count = va_arg(ap, uint32_t); |
442 | const void *data = va_arg(ap, const void *); | 440 | const void *data = va_arg(ap, const void *); |
443 | 441 | ||
444 | errcode = p9pdu_writef(pdu, proto_version, "d", | 442 | errcode = p9pdu_writef(pdu, proto_version, "d", |
diff --git a/net/Kconfig b/net/Kconfig index ad0aafe903f8..72840626284b 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
@@ -253,7 +253,9 @@ config NET_TCPPROBE | |||
253 | what was just said, you don't need it: say N. | 253 | what was just said, you don't need it: say N. |
254 | 254 | ||
255 | Documentation on how to use TCP connection probing can be found | 255 | Documentation on how to use TCP connection probing can be found |
256 | at http://linux-net.osdl.org/index.php/TcpProbe | 256 | at: |
257 | |||
258 | http://www.linuxfoundation.org/collaborate/workgroups/networking/tcpprobe | ||
257 | 259 | ||
258 | To compile this code as a module, choose M here: the | 260 | To compile this code as a module, choose M here: the |
259 | module will be called tcp_probe. | 261 | module will be called tcp_probe. |
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index cd4c4231fa48..de1022cacaf7 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -64,6 +64,7 @@ static void free_info(struct kref *ref) | |||
64 | 64 | ||
65 | spin_unlock_bh(&bat_priv->vis_list_lock); | 65 | spin_unlock_bh(&bat_priv->vis_list_lock); |
66 | kfree_skb(info->skb_packet); | 66 | kfree_skb(info->skb_packet); |
67 | kfree(info); | ||
67 | } | 68 | } |
68 | 69 | ||
69 | /* Compare two vis packets, used by the hashing algorithm */ | 70 | /* Compare two vis packets, used by the hashing algorithm */ |
@@ -268,10 +269,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) | |||
268 | buff_pos += sprintf(buff + buff_pos, "%pM,", | 269 | buff_pos += sprintf(buff + buff_pos, "%pM,", |
269 | entry->addr); | 270 | entry->addr); |
270 | 271 | ||
271 | for (i = 0; i < packet->entries; i++) | 272 | for (j = 0; j < packet->entries; j++) |
272 | buff_pos += vis_data_read_entry( | 273 | buff_pos += vis_data_read_entry( |
273 | buff + buff_pos, | 274 | buff + buff_pos, |
274 | &entries[i], | 275 | &entries[j], |
275 | entry->addr, | 276 | entry->addr, |
276 | entry->primary); | 277 | entry->primary); |
277 | 278 | ||
@@ -444,7 +445,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, | |||
444 | info); | 445 | info); |
445 | if (hash_added < 0) { | 446 | if (hash_added < 0) { |
446 | /* did not work (for some reason) */ | 447 | /* did not work (for some reason) */ |
447 | kref_put(&old_info->refcount, free_info); | 448 | kref_put(&info->refcount, free_info); |
448 | info = NULL; | 449 | info = NULL; |
449 | } | 450 | } |
450 | 451 | ||
@@ -815,7 +816,7 @@ static void send_vis_packets(struct work_struct *work) | |||
815 | container_of(work, struct delayed_work, work); | 816 | container_of(work, struct delayed_work, work); |
816 | struct bat_priv *bat_priv = | 817 | struct bat_priv *bat_priv = |
817 | container_of(delayed_work, struct bat_priv, vis_work); | 818 | container_of(delayed_work, struct bat_priv, vis_work); |
818 | struct vis_info *info, *temp; | 819 | struct vis_info *info; |
819 | 820 | ||
820 | spin_lock_bh(&bat_priv->vis_hash_lock); | 821 | spin_lock_bh(&bat_priv->vis_hash_lock); |
821 | purge_vis_packets(bat_priv); | 822 | purge_vis_packets(bat_priv); |
@@ -825,8 +826,9 @@ static void send_vis_packets(struct work_struct *work) | |||
825 | send_list_add(bat_priv, bat_priv->my_vis_info); | 826 | send_list_add(bat_priv, bat_priv->my_vis_info); |
826 | } | 827 | } |
827 | 828 | ||
828 | list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list, | 829 | while (!list_empty(&bat_priv->vis_send_list)) { |
829 | send_list) { | 830 | info = list_first_entry(&bat_priv->vis_send_list, |
831 | typeof(*info), send_list); | ||
830 | 832 | ||
831 | kref_get(&info->refcount); | 833 | kref_get(&info->refcount); |
832 | spin_unlock_bh(&bat_priv->vis_hash_lock); | 834 | spin_unlock_bh(&bat_priv->vis_hash_lock); |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6b90a4191734..99cd8d9d891b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -379,14 +379,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
379 | hci_conn_hold(acl); | 379 | hci_conn_hold(acl); |
380 | 380 | ||
381 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { | 381 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { |
382 | acl->sec_level = sec_level; | 382 | acl->sec_level = BT_SECURITY_LOW; |
383 | acl->pending_sec_level = sec_level; | ||
383 | acl->auth_type = auth_type; | 384 | acl->auth_type = auth_type; |
384 | hci_acl_connect(acl); | 385 | hci_acl_connect(acl); |
385 | } else { | ||
386 | if (acl->sec_level < sec_level) | ||
387 | acl->sec_level = sec_level; | ||
388 | if (acl->auth_type < auth_type) | ||
389 | acl->auth_type = auth_type; | ||
390 | } | 386 | } |
391 | 387 | ||
392 | if (type == ACL_LINK) | 388 | if (type == ACL_LINK) |
@@ -442,11 +438,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
442 | { | 438 | { |
443 | BT_DBG("conn %p", conn); | 439 | BT_DBG("conn %p", conn); |
444 | 440 | ||
441 | if (conn->pending_sec_level > sec_level) | ||
442 | sec_level = conn->pending_sec_level; | ||
443 | |||
445 | if (sec_level > conn->sec_level) | 444 | if (sec_level > conn->sec_level) |
446 | conn->sec_level = sec_level; | 445 | conn->pending_sec_level = sec_level; |
447 | else if (conn->link_mode & HCI_LM_AUTH) | 446 | else if (conn->link_mode & HCI_LM_AUTH) |
448 | return 1; | 447 | return 1; |
449 | 448 | ||
449 | /* Make sure we preserve an existing MITM requirement*/ | ||
450 | auth_type |= (conn->auth_type & 0x01); | ||
451 | |||
450 | conn->auth_type = auth_type; | 452 | conn->auth_type = auth_type; |
451 | 453 | ||
452 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 454 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8b602d881fd7..9c4541bc488a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1011,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1011 | 1011 | ||
1012 | destroy_workqueue(hdev->workqueue); | 1012 | destroy_workqueue(hdev->workqueue); |
1013 | 1013 | ||
1014 | hci_dev_lock_bh(hdev); | ||
1015 | hci_blacklist_clear(hdev); | ||
1016 | hci_dev_unlock_bh(hdev); | ||
1017 | |||
1014 | __hci_dev_put(hdev); | 1018 | __hci_dev_put(hdev); |
1015 | 1019 | ||
1016 | return 0; | 1020 | return 0; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 38100170d380..a290854fdaa6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, | |||
692 | if (conn->state != BT_CONFIG || !conn->out) | 692 | if (conn->state != BT_CONFIG || !conn->out) |
693 | return 0; | 693 | return 0; |
694 | 694 | ||
695 | if (conn->sec_level == BT_SECURITY_SDP) | 695 | if (conn->pending_sec_level == BT_SECURITY_SDP) |
696 | return 0; | 696 | return 0; |
697 | 697 | ||
698 | /* Only request authentication for SSP connections or non-SSP | 698 | /* Only request authentication for SSP connections or non-SSP |
699 | * devices with sec_level HIGH */ | 699 | * devices with sec_level HIGH */ |
700 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && | 700 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && |
701 | conn->sec_level != BT_SECURITY_HIGH) | 701 | conn->pending_sec_level != BT_SECURITY_HIGH) |
702 | return 0; | 702 | return 0; |
703 | 703 | ||
704 | return 1; | 704 | return 1; |
@@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1095 | 1095 | ||
1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1096 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
1097 | if (conn) { | 1097 | if (conn) { |
1098 | if (!ev->status) | 1098 | if (!ev->status) { |
1099 | conn->link_mode |= HCI_LM_AUTH; | 1099 | conn->link_mode |= HCI_LM_AUTH; |
1100 | else | 1100 | conn->sec_level = conn->pending_sec_level; |
1101 | } else | ||
1101 | conn->sec_level = BT_SECURITY_LOW; | 1102 | conn->sec_level = BT_SECURITY_LOW; |
1102 | 1103 | ||
1103 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); | 1104 | clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c791fcda7b2d..7550abb0c96a 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -305,33 +305,44 @@ static void l2cap_chan_del(struct sock *sk, int err) | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | 307 | ||
308 | /* Service level security */ | 308 | static inline u8 l2cap_get_auth_type(struct sock *sk) |
309 | static inline int l2cap_check_security(struct sock *sk) | ||
310 | { | 309 | { |
311 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 310 | if (sk->sk_type == SOCK_RAW) { |
312 | __u8 auth_type; | 311 | switch (l2cap_pi(sk)->sec_level) { |
312 | case BT_SECURITY_HIGH: | ||
313 | return HCI_AT_DEDICATED_BONDING_MITM; | ||
314 | case BT_SECURITY_MEDIUM: | ||
315 | return HCI_AT_DEDICATED_BONDING; | ||
316 | default: | ||
317 | return HCI_AT_NO_BONDING; | ||
318 | } | ||
319 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
320 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | ||
321 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
313 | 322 | ||
314 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
315 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | 323 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) |
316 | auth_type = HCI_AT_NO_BONDING_MITM; | 324 | return HCI_AT_NO_BONDING_MITM; |
317 | else | 325 | else |
318 | auth_type = HCI_AT_NO_BONDING; | 326 | return HCI_AT_NO_BONDING; |
319 | |||
320 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | ||
321 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
322 | } else { | 327 | } else { |
323 | switch (l2cap_pi(sk)->sec_level) { | 328 | switch (l2cap_pi(sk)->sec_level) { |
324 | case BT_SECURITY_HIGH: | 329 | case BT_SECURITY_HIGH: |
325 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | 330 | return HCI_AT_GENERAL_BONDING_MITM; |
326 | break; | ||
327 | case BT_SECURITY_MEDIUM: | 331 | case BT_SECURITY_MEDIUM: |
328 | auth_type = HCI_AT_GENERAL_BONDING; | 332 | return HCI_AT_GENERAL_BONDING; |
329 | break; | ||
330 | default: | 333 | default: |
331 | auth_type = HCI_AT_NO_BONDING; | 334 | return HCI_AT_NO_BONDING; |
332 | break; | ||
333 | } | 335 | } |
334 | } | 336 | } |
337 | } | ||
338 | |||
339 | /* Service level security */ | ||
340 | static inline int l2cap_check_security(struct sock *sk) | ||
341 | { | ||
342 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
343 | __u8 auth_type; | ||
344 | |||
345 | auth_type = l2cap_get_auth_type(sk); | ||
335 | 346 | ||
336 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, | 347 | return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, |
337 | auth_type); | 348 | auth_type); |
@@ -1068,39 +1079,7 @@ static int l2cap_do_connect(struct sock *sk) | |||
1068 | 1079 | ||
1069 | err = -ENOMEM; | 1080 | err = -ENOMEM; |
1070 | 1081 | ||
1071 | if (sk->sk_type == SOCK_RAW) { | 1082 | auth_type = l2cap_get_auth_type(sk); |
1072 | switch (l2cap_pi(sk)->sec_level) { | ||
1073 | case BT_SECURITY_HIGH: | ||
1074 | auth_type = HCI_AT_DEDICATED_BONDING_MITM; | ||
1075 | break; | ||
1076 | case BT_SECURITY_MEDIUM: | ||
1077 | auth_type = HCI_AT_DEDICATED_BONDING; | ||
1078 | break; | ||
1079 | default: | ||
1080 | auth_type = HCI_AT_NO_BONDING; | ||
1081 | break; | ||
1082 | } | ||
1083 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
1084 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | ||
1085 | auth_type = HCI_AT_NO_BONDING_MITM; | ||
1086 | else | ||
1087 | auth_type = HCI_AT_NO_BONDING; | ||
1088 | |||
1089 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | ||
1090 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
1091 | } else { | ||
1092 | switch (l2cap_pi(sk)->sec_level) { | ||
1093 | case BT_SECURITY_HIGH: | ||
1094 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
1095 | break; | ||
1096 | case BT_SECURITY_MEDIUM: | ||
1097 | auth_type = HCI_AT_GENERAL_BONDING; | ||
1098 | break; | ||
1099 | default: | ||
1100 | auth_type = HCI_AT_NO_BONDING; | ||
1101 | break; | ||
1102 | } | ||
1103 | } | ||
1104 | 1083 | ||
1105 | hcon = hci_connect(hdev, ACL_LINK, dst, | 1084 | hcon = hci_connect(hdev, ACL_LINK, dst, |
1106 | l2cap_pi(sk)->sec_level, auth_type); | 1085 | l2cap_pi(sk)->sec_level, auth_type); |
@@ -1127,7 +1106,8 @@ static int l2cap_do_connect(struct sock *sk) | |||
1127 | if (sk->sk_type != SOCK_SEQPACKET && | 1106 | if (sk->sk_type != SOCK_SEQPACKET && |
1128 | sk->sk_type != SOCK_STREAM) { | 1107 | sk->sk_type != SOCK_STREAM) { |
1129 | l2cap_sock_clear_timer(sk); | 1108 | l2cap_sock_clear_timer(sk); |
1130 | sk->sk_state = BT_CONNECTED; | 1109 | if (l2cap_check_security(sk)) |
1110 | sk->sk_state = BT_CONNECTED; | ||
1131 | } else | 1111 | } else |
1132 | l2cap_do_start(sk); | 1112 | l2cap_do_start(sk); |
1133 | } | 1113 | } |
@@ -1893,8 +1873,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms | |||
1893 | if (pi->mode == L2CAP_MODE_STREAMING) { | 1873 | if (pi->mode == L2CAP_MODE_STREAMING) { |
1894 | l2cap_streaming_send(sk); | 1874 | l2cap_streaming_send(sk); |
1895 | } else { | 1875 | } else { |
1896 | if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && | 1876 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && |
1897 | pi->conn_state && L2CAP_CONN_WAIT_F) { | 1877 | (pi->conn_state & L2CAP_CONN_WAIT_F)) { |
1898 | err = len; | 1878 | err = len; |
1899 | break; | 1879 | break; |
1900 | } | 1880 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index ff8aaa736650..6b83776534fb 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -1164,7 +1164,8 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | |||
1164 | * initiator rfcomm_process_rx already calls | 1164 | * initiator rfcomm_process_rx already calls |
1165 | * rfcomm_session_put() */ | 1165 | * rfcomm_session_put() */ |
1166 | if (s->sock->sk->sk_state != BT_CLOSED) | 1166 | if (s->sock->sk->sk_state != BT_CLOSED) |
1167 | rfcomm_session_put(s); | 1167 | if (list_empty(&s->dlcs)) |
1168 | rfcomm_session_put(s); | ||
1168 | break; | 1169 | break; |
1169 | } | 1170 | } |
1170 | } | 1171 | } |
diff --git a/net/ceph/ceph_hash.c b/net/ceph/ceph_hash.c index 815ef8826796..0a1b53bce76d 100644 --- a/net/ceph/ceph_hash.c +++ b/net/ceph/ceph_hash.c | |||
@@ -1,5 +1,6 @@ | |||
1 | 1 | ||
2 | #include <linux/ceph/types.h> | 2 | #include <linux/ceph/types.h> |
3 | #include <linux/module.h> | ||
3 | 4 | ||
4 | /* | 5 | /* |
5 | * Robert Jenkin's hash function. | 6 | * Robert Jenkin's hash function. |
@@ -104,6 +105,7 @@ unsigned ceph_str_hash(int type, const char *s, unsigned len) | |||
104 | return -1; | 105 | return -1; |
105 | } | 106 | } |
106 | } | 107 | } |
108 | EXPORT_SYMBOL(ceph_str_hash); | ||
107 | 109 | ||
108 | const char *ceph_str_hash_name(int type) | 110 | const char *ceph_str_hash_name(int type) |
109 | { | 111 | { |
@@ -116,3 +118,4 @@ const char *ceph_str_hash_name(int type) | |||
116 | return "unknown"; | 118 | return "unknown"; |
117 | } | 119 | } |
118 | } | 120 | } |
121 | EXPORT_SYMBOL(ceph_str_hash_name); | ||
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index b6ff4a1519ab..dff633d62e5b 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -96,7 +96,7 @@ struct workqueue_struct *ceph_msgr_wq; | |||
96 | 96 | ||
97 | int ceph_msgr_init(void) | 97 | int ceph_msgr_init(void) |
98 | { | 98 | { |
99 | ceph_msgr_wq = create_workqueue("ceph-msgr"); | 99 | ceph_msgr_wq = alloc_workqueue("ceph-msgr", WQ_NON_REENTRANT, 0); |
100 | if (!ceph_msgr_wq) { | 100 | if (!ceph_msgr_wq) { |
101 | pr_err("msgr_init failed to create workqueue\n"); | 101 | pr_err("msgr_init failed to create workqueue\n"); |
102 | return -ENOMEM; | 102 | return -ENOMEM; |
@@ -1920,20 +1920,6 @@ bad_tag: | |||
1920 | /* | 1920 | /* |
1921 | * Atomically queue work on a connection. Bump @con reference to | 1921 | * Atomically queue work on a connection. Bump @con reference to |
1922 | * avoid races with connection teardown. | 1922 | * avoid races with connection teardown. |
1923 | * | ||
1924 | * There is some trickery going on with QUEUED and BUSY because we | ||
1925 | * only want a _single_ thread operating on each connection at any | ||
1926 | * point in time, but we want to use all available CPUs. | ||
1927 | * | ||
1928 | * The worker thread only proceeds if it can atomically set BUSY. It | ||
1929 | * clears QUEUED and does it's thing. When it thinks it's done, it | ||
1930 | * clears BUSY, then rechecks QUEUED.. if it's set again, it loops | ||
1931 | * (tries again to set BUSY). | ||
1932 | * | ||
1933 | * To queue work, we first set QUEUED, _then_ if BUSY isn't set, we | ||
1934 | * try to queue work. If that fails (work is already queued, or BUSY) | ||
1935 | * we give up (work also already being done or is queued) but leave QUEUED | ||
1936 | * set so that the worker thread will loop if necessary. | ||
1937 | */ | 1923 | */ |
1938 | static void queue_con(struct ceph_connection *con) | 1924 | static void queue_con(struct ceph_connection *con) |
1939 | { | 1925 | { |
@@ -1948,11 +1934,7 @@ static void queue_con(struct ceph_connection *con) | |||
1948 | return; | 1934 | return; |
1949 | } | 1935 | } |
1950 | 1936 | ||
1951 | set_bit(QUEUED, &con->state); | 1937 | if (!queue_delayed_work(ceph_msgr_wq, &con->work, 0)) { |
1952 | if (test_bit(BUSY, &con->state)) { | ||
1953 | dout("queue_con %p - already BUSY\n", con); | ||
1954 | con->ops->put(con); | ||
1955 | } else if (!queue_work(ceph_msgr_wq, &con->work.work)) { | ||
1956 | dout("queue_con %p - already queued\n", con); | 1938 | dout("queue_con %p - already queued\n", con); |
1957 | con->ops->put(con); | 1939 | con->ops->put(con); |
1958 | } else { | 1940 | } else { |
@@ -1967,15 +1949,6 @@ static void con_work(struct work_struct *work) | |||
1967 | { | 1949 | { |
1968 | struct ceph_connection *con = container_of(work, struct ceph_connection, | 1950 | struct ceph_connection *con = container_of(work, struct ceph_connection, |
1969 | work.work); | 1951 | work.work); |
1970 | int backoff = 0; | ||
1971 | |||
1972 | more: | ||
1973 | if (test_and_set_bit(BUSY, &con->state) != 0) { | ||
1974 | dout("con_work %p BUSY already set\n", con); | ||
1975 | goto out; | ||
1976 | } | ||
1977 | dout("con_work %p start, clearing QUEUED\n", con); | ||
1978 | clear_bit(QUEUED, &con->state); | ||
1979 | 1952 | ||
1980 | mutex_lock(&con->mutex); | 1953 | mutex_lock(&con->mutex); |
1981 | 1954 | ||
@@ -1994,28 +1967,13 @@ more: | |||
1994 | try_read(con) < 0 || | 1967 | try_read(con) < 0 || |
1995 | try_write(con) < 0) { | 1968 | try_write(con) < 0) { |
1996 | mutex_unlock(&con->mutex); | 1969 | mutex_unlock(&con->mutex); |
1997 | backoff = 1; | ||
1998 | ceph_fault(con); /* error/fault path */ | 1970 | ceph_fault(con); /* error/fault path */ |
1999 | goto done_unlocked; | 1971 | goto done_unlocked; |
2000 | } | 1972 | } |
2001 | 1973 | ||
2002 | done: | 1974 | done: |
2003 | mutex_unlock(&con->mutex); | 1975 | mutex_unlock(&con->mutex); |
2004 | |||
2005 | done_unlocked: | 1976 | done_unlocked: |
2006 | clear_bit(BUSY, &con->state); | ||
2007 | dout("con->state=%lu\n", con->state); | ||
2008 | if (test_bit(QUEUED, &con->state)) { | ||
2009 | if (!backoff || test_bit(OPENING, &con->state)) { | ||
2010 | dout("con_work %p QUEUED reset, looping\n", con); | ||
2011 | goto more; | ||
2012 | } | ||
2013 | dout("con_work %p QUEUED reset, but just faulted\n", con); | ||
2014 | clear_bit(QUEUED, &con->state); | ||
2015 | } | ||
2016 | dout("con_work %p done\n", con); | ||
2017 | |||
2018 | out: | ||
2019 | con->ops->put(con); | 1977 | con->ops->put(con); |
2020 | } | 1978 | } |
2021 | 1979 | ||
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index d73f3f6efa36..71603ac3dff5 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -605,8 +605,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
605 | goto bad; | 605 | goto bad; |
606 | } | 606 | } |
607 | err = __decode_pool(p, end, pi); | 607 | err = __decode_pool(p, end, pi); |
608 | if (err < 0) | 608 | if (err < 0) { |
609 | kfree(pi); | ||
609 | goto bad; | 610 | goto bad; |
611 | } | ||
610 | __insert_pg_pool(&map->pg_pools, pi); | 612 | __insert_pg_pool(&map->pg_pools, pi); |
611 | } | 613 | } |
612 | 614 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 8393ec408cd4..b6d0bf875a8e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -749,7 +749,8 @@ EXPORT_SYMBOL(dev_get_by_index); | |||
749 | * @ha: hardware address | 749 | * @ha: hardware address |
750 | * | 750 | * |
751 | * Search for an interface by MAC address. Returns NULL if the device | 751 | * Search for an interface by MAC address. Returns NULL if the device |
752 | * is not found or a pointer to the device. The caller must hold RCU | 752 | * is not found or a pointer to the device. |
753 | * The caller must hold RCU or RTNL. | ||
753 | * The returned device has not had its ref count increased | 754 | * The returned device has not had its ref count increased |
754 | * and the caller must therefore be careful about locking | 755 | * and the caller must therefore be careful about locking |
755 | * | 756 | * |
@@ -2562,7 +2563,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2562 | 2563 | ||
2563 | map = rcu_dereference(rxqueue->rps_map); | 2564 | map = rcu_dereference(rxqueue->rps_map); |
2564 | if (map) { | 2565 | if (map) { |
2565 | if (map->len == 1) { | 2566 | if (map->len == 1 && |
2567 | !rcu_dereference_raw(rxqueue->rps_flow_table)) { | ||
2566 | tcpu = map->cpus[0]; | 2568 | tcpu = map->cpus[0]; |
2567 | if (cpu_online(tcpu)) | 2569 | if (cpu_online(tcpu)) |
2568 | cpu = tcpu; | 2570 | cpu = tcpu; |
@@ -3423,6 +3425,8 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
3423 | __skb_pull(skb, skb_headlen(skb)); | 3425 | __skb_pull(skb, skb_headlen(skb)); |
3424 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | 3426 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); |
3425 | skb->vlan_tci = 0; | 3427 | skb->vlan_tci = 0; |
3428 | skb->dev = napi->dev; | ||
3429 | skb->skb_iif = 0; | ||
3426 | 3430 | ||
3427 | napi->skb = skb; | 3431 | napi->skb = skb; |
3428 | } | 3432 | } |
@@ -6189,7 +6193,7 @@ static void __net_exit default_device_exit(struct net *net) | |||
6189 | static void __net_exit default_device_exit_batch(struct list_head *net_list) | 6193 | static void __net_exit default_device_exit_batch(struct list_head *net_list) |
6190 | { | 6194 | { |
6191 | /* At exit all network devices most be removed from a network | 6195 | /* At exit all network devices most be removed from a network |
6192 | * namespace. Do this in the reverse order of registeration. | 6196 | * namespace. Do this in the reverse order of registration. |
6193 | * Do this across as many network namespaces as possible to | 6197 | * Do this across as many network namespaces as possible to |
6194 | * improve batching efficiency. | 6198 | * improve batching efficiency. |
6195 | */ | 6199 | */ |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 17741782a345..ff2302910b5e 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -817,7 +817,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | |||
817 | if (regs.len > reglen) | 817 | if (regs.len > reglen) |
818 | regs.len = reglen; | 818 | regs.len = reglen; |
819 | 819 | ||
820 | regbuf = vmalloc(reglen); | 820 | regbuf = vzalloc(reglen); |
821 | if (!regbuf) | 821 | if (!regbuf) |
822 | return -ENOMEM; | 822 | return -ENOMEM; |
823 | 823 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 750db57f3bb3..2d65c6bb24c1 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1121,8 +1121,7 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) | |||
1121 | return -EOPNOTSUPP; | 1121 | return -EOPNOTSUPP; |
1122 | 1122 | ||
1123 | if (af_ops->validate_link_af) { | 1123 | if (af_ops->validate_link_af) { |
1124 | err = af_ops->validate_link_af(dev, | 1124 | err = af_ops->validate_link_af(dev, af); |
1125 | tb[IFLA_AF_SPEC]); | ||
1126 | if (err < 0) | 1125 | if (err < 0) |
1127 | return err; | 1126 | return err; |
1128 | } | 1127 | } |
@@ -1672,6 +1671,9 @@ replay: | |||
1672 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); | 1671 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); |
1673 | 1672 | ||
1674 | dest_net = rtnl_link_get_net(net, tb); | 1673 | dest_net = rtnl_link_get_net(net, tb); |
1674 | if (IS_ERR(dest_net)) | ||
1675 | return PTR_ERR(dest_net); | ||
1676 | |||
1675 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); | 1677 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); |
1676 | 1678 | ||
1677 | if (IS_ERR(dev)) | 1679 | if (IS_ERR(dev)) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index d31bb36ae0dc..d883dcc78b6b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -210,6 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
210 | shinfo = skb_shinfo(skb); | 210 | shinfo = skb_shinfo(skb); |
211 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | 211 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); |
212 | atomic_set(&shinfo->dataref, 1); | 212 | atomic_set(&shinfo->dataref, 1); |
213 | kmemcheck_annotate_variable(shinfo->destructor_arg); | ||
213 | 214 | ||
214 | if (fclone) { | 215 | if (fclone) { |
215 | struct sk_buff *child = skb + 1; | 216 | struct sk_buff *child = skb + 1; |
@@ -2744,8 +2745,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
2744 | 2745 | ||
2745 | merge: | 2746 | merge: |
2746 | if (offset > headlen) { | 2747 | if (offset > headlen) { |
2747 | skbinfo->frags[0].page_offset += offset - headlen; | 2748 | unsigned int eat = offset - headlen; |
2748 | skbinfo->frags[0].size -= offset - headlen; | 2749 | |
2750 | skbinfo->frags[0].page_offset += eat; | ||
2751 | skbinfo->frags[0].size -= eat; | ||
2752 | skb->data_len -= eat; | ||
2753 | skb->len -= eat; | ||
2749 | offset = headlen; | 2754 | offset = headlen; |
2750 | } | 2755 | } |
2751 | 2756 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index a658aeb6d554..7dfed792434d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -157,7 +157,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
157 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , | 157 | "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , |
158 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 158 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
159 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 159 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
160 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , | 160 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
161 | "sk_lock-AF_MAX" | 161 | "sk_lock-AF_MAX" |
162 | }; | 162 | }; |
163 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 163 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
@@ -173,7 +173,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
173 | "slock-27" , "slock-28" , "slock-AF_CAN" , | 173 | "slock-27" , "slock-28" , "slock-AF_CAN" , |
174 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 174 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
175 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 175 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
176 | "slock-AF_IEEE802154", "slock-AF_CAIF" , | 176 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
177 | "slock-AF_MAX" | 177 | "slock-AF_MAX" |
178 | }; | 178 | }; |
179 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 179 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
@@ -189,7 +189,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
189 | "clock-27" , "clock-28" , "clock-AF_CAN" , | 189 | "clock-27" , "clock-28" , "clock-AF_CAN" , |
190 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 190 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
191 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 191 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
192 | "clock-AF_IEEE802154", "clock-AF_CAIF" , | 192 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
193 | "clock-AF_MAX" | 193 | "clock-AF_MAX" |
194 | }; | 194 | }; |
195 | 195 | ||
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index d900ab99814a..6b03f561caec 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -583,7 +583,7 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, | |||
583 | u8 up, idtype; | 583 | u8 up, idtype; |
584 | int ret = -EINVAL; | 584 | int ret = -EINVAL; |
585 | 585 | ||
586 | if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->getapp) | 586 | if (!tb[DCB_ATTR_APP]) |
587 | goto out; | 587 | goto out; |
588 | 588 | ||
589 | ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], | 589 | ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], |
@@ -604,7 +604,16 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, | |||
604 | goto out; | 604 | goto out; |
605 | 605 | ||
606 | id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); | 606 | id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); |
607 | up = netdev->dcbnl_ops->getapp(netdev, idtype, id); | 607 | |
608 | if (netdev->dcbnl_ops->getapp) { | ||
609 | up = netdev->dcbnl_ops->getapp(netdev, idtype, id); | ||
610 | } else { | ||
611 | struct dcb_app app = { | ||
612 | .selector = idtype, | ||
613 | .protocol = id, | ||
614 | }; | ||
615 | up = dcb_getapp(netdev, &app); | ||
616 | } | ||
608 | 617 | ||
609 | /* send this back */ | 618 | /* send this back */ |
610 | dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 619 | dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig index ad6dffd9070e..b75968a04017 100644 --- a/net/dccp/Kconfig +++ b/net/dccp/Kconfig | |||
@@ -49,7 +49,9 @@ config NET_DCCPPROBE | |||
49 | what was just said, you don't need it: say N. | 49 | what was just said, you don't need it: say N. |
50 | 50 | ||
51 | Documentation on how to use DCCP connection probing can be found | 51 | Documentation on how to use DCCP connection probing can be found |
52 | at http://linux-net.osdl.org/index.php/DccpProbe | 52 | at: |
53 | |||
54 | http://www.linuxfoundation.org/collaborate/workgroups/networking/dccpprobe | ||
53 | 55 | ||
54 | To compile this code as a module, choose M here: the | 56 | To compile this code as a module, choose M here: the |
55 | module will be called dccp_probe. | 57 | module will be called dccp_probe. |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 0ba15633c418..0dcaa903e00e 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -1130,7 +1130,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) | |||
1130 | /* | 1130 | /* |
1131 | * This processes a device up event. We only start up | 1131 | * This processes a device up event. We only start up |
1132 | * the loopback device & ethernet devices with correct | 1132 | * the loopback device & ethernet devices with correct |
1133 | * MAC addreses automatically. Others must be started | 1133 | * MAC addresses automatically. Others must be started |
1134 | * specifically. | 1134 | * specifically. |
1135 | * | 1135 | * |
1136 | * FIXME: How should we configure the loopback address ? If we could dispense | 1136 | * FIXME: How should we configure the loopback address ? If we could dispense |
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 0c877a74e1f4..3fb14b7c13cf 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -428,7 +428,7 @@ static void __exit dsa_cleanup_module(void) | |||
428 | } | 428 | } |
429 | module_exit(dsa_cleanup_module); | 429 | module_exit(dsa_cleanup_module); |
430 | 430 | ||
431 | MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>") | 431 | MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); |
432 | MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips"); | 432 | MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips"); |
433 | MODULE_LICENSE("GPL"); | 433 | MODULE_LICENSE("GPL"); |
434 | MODULE_ALIAS("platform:dsa"); | 434 | MODULE_ALIAS("platform:dsa"); |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 15dcc1a586b4..0c2826337919 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -265,13 +265,13 @@ static void ec_tx_done(struct sk_buff *skb, int result) | |||
265 | static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | 265 | static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, |
266 | struct msghdr *msg, size_t len) | 266 | struct msghdr *msg, size_t len) |
267 | { | 267 | { |
268 | struct sock *sk = sock->sk; | ||
269 | struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name; | 268 | struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name; |
270 | struct net_device *dev; | 269 | struct net_device *dev; |
271 | struct ec_addr addr; | 270 | struct ec_addr addr; |
272 | int err; | 271 | int err; |
273 | unsigned char port, cb; | 272 | unsigned char port, cb; |
274 | #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) | 273 | #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) |
274 | struct sock *sk = sock->sk; | ||
275 | struct sk_buff *skb; | 275 | struct sk_buff *skb; |
276 | struct ec_cb *eb; | 276 | struct ec_cb *eb; |
277 | #endif | 277 | #endif |
@@ -488,10 +488,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
488 | 488 | ||
489 | error_free_buf: | 489 | error_free_buf: |
490 | vfree(userbuf); | 490 | vfree(userbuf); |
491 | error: | ||
491 | #else | 492 | #else |
492 | err = -EPROTOTYPE; | 493 | err = -EPROTOTYPE; |
493 | #endif | 494 | #endif |
494 | error: | ||
495 | mutex_unlock(&econet_mutex); | 495 | mutex_unlock(&econet_mutex); |
496 | 496 | ||
497 | return err; | 497 | return err; |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 9e95d7fb6d5a..a5a1050595d1 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -432,7 +432,9 @@ config INET_DIAG | |||
432 | ---help--- | 432 | ---help--- |
433 | Support for INET (TCP, DCCP, etc) socket monitoring interface used by | 433 | Support for INET (TCP, DCCP, etc) socket monitoring interface used by |
434 | native Linux tools such as ss. ss is included in iproute2, currently | 434 | native Linux tools such as ss. ss is included in iproute2, currently |
435 | downloadable at <http://linux-net.osdl.org/index.php/Iproute2>. | 435 | downloadable at: |
436 | |||
437 | http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 | ||
436 | 438 | ||
437 | If unsure, say Y. | 439 | If unsure, say Y. |
438 | 440 | ||
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f2b61107df6c..45b89d7bda5a 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -880,6 +880,19 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
880 | } | 880 | } |
881 | EXPORT_SYMBOL(inet_ioctl); | 881 | EXPORT_SYMBOL(inet_ioctl); |
882 | 882 | ||
883 | #ifdef CONFIG_COMPAT | ||
884 | int inet_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
885 | { | ||
886 | struct sock *sk = sock->sk; | ||
887 | int err = -ENOIOCTLCMD; | ||
888 | |||
889 | if (sk->sk_prot->compat_ioctl) | ||
890 | err = sk->sk_prot->compat_ioctl(sk, cmd, arg); | ||
891 | |||
892 | return err; | ||
893 | } | ||
894 | #endif | ||
895 | |||
883 | const struct proto_ops inet_stream_ops = { | 896 | const struct proto_ops inet_stream_ops = { |
884 | .family = PF_INET, | 897 | .family = PF_INET, |
885 | .owner = THIS_MODULE, | 898 | .owner = THIS_MODULE, |
@@ -903,6 +916,7 @@ const struct proto_ops inet_stream_ops = { | |||
903 | #ifdef CONFIG_COMPAT | 916 | #ifdef CONFIG_COMPAT |
904 | .compat_setsockopt = compat_sock_common_setsockopt, | 917 | .compat_setsockopt = compat_sock_common_setsockopt, |
905 | .compat_getsockopt = compat_sock_common_getsockopt, | 918 | .compat_getsockopt = compat_sock_common_getsockopt, |
919 | .compat_ioctl = inet_compat_ioctl, | ||
906 | #endif | 920 | #endif |
907 | }; | 921 | }; |
908 | EXPORT_SYMBOL(inet_stream_ops); | 922 | EXPORT_SYMBOL(inet_stream_ops); |
@@ -929,6 +943,7 @@ const struct proto_ops inet_dgram_ops = { | |||
929 | #ifdef CONFIG_COMPAT | 943 | #ifdef CONFIG_COMPAT |
930 | .compat_setsockopt = compat_sock_common_setsockopt, | 944 | .compat_setsockopt = compat_sock_common_setsockopt, |
931 | .compat_getsockopt = compat_sock_common_getsockopt, | 945 | .compat_getsockopt = compat_sock_common_getsockopt, |
946 | .compat_ioctl = inet_compat_ioctl, | ||
932 | #endif | 947 | #endif |
933 | }; | 948 | }; |
934 | EXPORT_SYMBOL(inet_dgram_ops); | 949 | EXPORT_SYMBOL(inet_dgram_ops); |
@@ -959,6 +974,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
959 | #ifdef CONFIG_COMPAT | 974 | #ifdef CONFIG_COMPAT |
960 | .compat_setsockopt = compat_sock_common_setsockopt, | 975 | .compat_setsockopt = compat_sock_common_setsockopt, |
961 | .compat_getsockopt = compat_sock_common_getsockopt, | 976 | .compat_getsockopt = compat_sock_common_getsockopt, |
977 | .compat_ioctl = inet_compat_ioctl, | ||
962 | #endif | 978 | #endif |
963 | }; | 979 | }; |
964 | 980 | ||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 04c8b69fd426..7927589813b5 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -1017,14 +1017,13 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on) | |||
1017 | IPV4_DEVCONF_ALL(net, PROXY_ARP) = on; | 1017 | IPV4_DEVCONF_ALL(net, PROXY_ARP) = on; |
1018 | return 0; | 1018 | return 0; |
1019 | } | 1019 | } |
1020 | if (__in_dev_get_rcu(dev)) { | 1020 | if (__in_dev_get_rtnl(dev)) { |
1021 | IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on); | 1021 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on); |
1022 | return 0; | 1022 | return 0; |
1023 | } | 1023 | } |
1024 | return -ENXIO; | 1024 | return -ENXIO; |
1025 | } | 1025 | } |
1026 | 1026 | ||
1027 | /* must be called with rcu_read_lock() */ | ||
1028 | static int arp_req_set_public(struct net *net, struct arpreq *r, | 1027 | static int arp_req_set_public(struct net *net, struct arpreq *r, |
1029 | struct net_device *dev) | 1028 | struct net_device *dev) |
1030 | { | 1029 | { |
@@ -1233,10 +1232,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
1233 | if (!(r.arp_flags & ATF_NETMASK)) | 1232 | if (!(r.arp_flags & ATF_NETMASK)) |
1234 | ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = | 1233 | ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = |
1235 | htonl(0xFFFFFFFFUL); | 1234 | htonl(0xFFFFFFFFUL); |
1236 | rcu_read_lock(); | 1235 | rtnl_lock(); |
1237 | if (r.arp_dev[0]) { | 1236 | if (r.arp_dev[0]) { |
1238 | err = -ENODEV; | 1237 | err = -ENODEV; |
1239 | dev = dev_get_by_name_rcu(net, r.arp_dev); | 1238 | dev = __dev_get_by_name(net, r.arp_dev); |
1240 | if (dev == NULL) | 1239 | if (dev == NULL) |
1241 | goto out; | 1240 | goto out; |
1242 | 1241 | ||
@@ -1263,7 +1262,7 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
1263 | break; | 1262 | break; |
1264 | } | 1263 | } |
1265 | out: | 1264 | out: |
1266 | rcu_read_unlock(); | 1265 | rtnl_unlock(); |
1267 | if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r))) | 1266 | if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r))) |
1268 | err = -EFAULT; | 1267 | err = -EFAULT; |
1269 | return err; | 1268 | return err; |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index d9bc85751c74..a96e65674ac3 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -475,7 +475,7 @@ static int cleanup_once(unsigned long ttl) | |||
475 | struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) | 475 | struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) |
476 | { | 476 | { |
477 | struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; | 477 | struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr; |
478 | struct inet_peer_base *base = family_to_base(AF_INET); | 478 | struct inet_peer_base *base = family_to_base(daddr->family); |
479 | struct inet_peer *p; | 479 | struct inet_peer *p; |
480 | 480 | ||
481 | /* Look up for the address quickly, lockless. | 481 | /* Look up for the address quickly, lockless. |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 3f3a9afd73e0..7e41ac0b9260 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/notifier.h> | 60 | #include <linux/notifier.h> |
61 | #include <linux/if_arp.h> | 61 | #include <linux/if_arp.h> |
62 | #include <linux/netfilter_ipv4.h> | 62 | #include <linux/netfilter_ipv4.h> |
63 | #include <linux/compat.h> | ||
63 | #include <net/ipip.h> | 64 | #include <net/ipip.h> |
64 | #include <net/checksum.h> | 65 | #include <net/checksum.h> |
65 | #include <net/netlink.h> | 66 | #include <net/netlink.h> |
@@ -1434,6 +1435,51 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1434 | } | 1435 | } |
1435 | } | 1436 | } |
1436 | 1437 | ||
1438 | #ifdef CONFIG_COMPAT | ||
1439 | struct compat_sioc_sg_req { | ||
1440 | struct in_addr src; | ||
1441 | struct in_addr grp; | ||
1442 | compat_ulong_t pktcnt; | ||
1443 | compat_ulong_t bytecnt; | ||
1444 | compat_ulong_t wrong_if; | ||
1445 | }; | ||
1446 | |||
1447 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
1448 | { | ||
1449 | struct sioc_sg_req sr; | ||
1450 | struct mfc_cache *c; | ||
1451 | struct net *net = sock_net(sk); | ||
1452 | struct mr_table *mrt; | ||
1453 | |||
1454 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
1455 | if (mrt == NULL) | ||
1456 | return -ENOENT; | ||
1457 | |||
1458 | switch (cmd) { | ||
1459 | case SIOCGETSGCNT: | ||
1460 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
1461 | return -EFAULT; | ||
1462 | |||
1463 | rcu_read_lock(); | ||
1464 | c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); | ||
1465 | if (c) { | ||
1466 | sr.pktcnt = c->mfc_un.res.pkt; | ||
1467 | sr.bytecnt = c->mfc_un.res.bytes; | ||
1468 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
1469 | rcu_read_unlock(); | ||
1470 | |||
1471 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
1472 | return -EFAULT; | ||
1473 | return 0; | ||
1474 | } | ||
1475 | rcu_read_unlock(); | ||
1476 | return -EADDRNOTAVAIL; | ||
1477 | default: | ||
1478 | return -ENOIOCTLCMD; | ||
1479 | } | ||
1480 | } | ||
1481 | #endif | ||
1482 | |||
1437 | 1483 | ||
1438 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) | 1484 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) |
1439 | { | 1485 | { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a3d5ab786e81..6390ba299b3d 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -76,6 +76,7 @@ | |||
76 | #include <linux/seq_file.h> | 76 | #include <linux/seq_file.h> |
77 | #include <linux/netfilter.h> | 77 | #include <linux/netfilter.h> |
78 | #include <linux/netfilter_ipv4.h> | 78 | #include <linux/netfilter_ipv4.h> |
79 | #include <linux/compat.h> | ||
79 | 80 | ||
80 | static struct raw_hashinfo raw_v4_hashinfo = { | 81 | static struct raw_hashinfo raw_v4_hashinfo = { |
81 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), | 82 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), |
@@ -838,6 +839,23 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
838 | } | 839 | } |
839 | } | 840 | } |
840 | 841 | ||
842 | #ifdef CONFIG_COMPAT | ||
843 | static int compat_raw_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
844 | { | ||
845 | switch (cmd) { | ||
846 | case SIOCOUTQ: | ||
847 | case SIOCINQ: | ||
848 | return -ENOIOCTLCMD; | ||
849 | default: | ||
850 | #ifdef CONFIG_IP_MROUTE | ||
851 | return ipmr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
852 | #else | ||
853 | return -ENOIOCTLCMD; | ||
854 | #endif | ||
855 | } | ||
856 | } | ||
857 | #endif | ||
858 | |||
841 | struct proto raw_prot = { | 859 | struct proto raw_prot = { |
842 | .name = "RAW", | 860 | .name = "RAW", |
843 | .owner = THIS_MODULE, | 861 | .owner = THIS_MODULE, |
@@ -860,6 +878,7 @@ struct proto raw_prot = { | |||
860 | #ifdef CONFIG_COMPAT | 878 | #ifdef CONFIG_COMPAT |
861 | .compat_setsockopt = compat_raw_setsockopt, | 879 | .compat_setsockopt = compat_raw_setsockopt, |
862 | .compat_getsockopt = compat_raw_getsockopt, | 880 | .compat_getsockopt = compat_raw_getsockopt, |
881 | .compat_ioctl = compat_raw_ioctl, | ||
863 | #endif | 882 | #endif |
864 | }; | 883 | }; |
865 | 884 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 351dc4e85242..788a3e74834e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2707,6 +2707,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo | |||
2707 | return NULL; | 2707 | return NULL; |
2708 | } | 2708 | } |
2709 | 2709 | ||
2710 | static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst) | ||
2711 | { | ||
2712 | return 0; | ||
2713 | } | ||
2714 | |||
2710 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2715 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
2711 | { | 2716 | { |
2712 | } | 2717 | } |
@@ -2716,6 +2721,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2716 | .protocol = cpu_to_be16(ETH_P_IP), | 2721 | .protocol = cpu_to_be16(ETH_P_IP), |
2717 | .destroy = ipv4_dst_destroy, | 2722 | .destroy = ipv4_dst_destroy, |
2718 | .check = ipv4_blackhole_dst_check, | 2723 | .check = ipv4_blackhole_dst_check, |
2724 | .default_mtu = ipv4_blackhole_default_mtu, | ||
2719 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2725 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2720 | }; | 2726 | }; |
2721 | 2727 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2549b29b062d..eb7f82ebf4a3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4399,7 +4399,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
4399 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { | 4399 | if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) { |
4400 | tp->ucopy.len -= chunk; | 4400 | tp->ucopy.len -= chunk; |
4401 | tp->copied_seq += chunk; | 4401 | tp->copied_seq += chunk; |
4402 | eaten = (chunk == skb->len && !th->fin); | 4402 | eaten = (chunk == skb->len); |
4403 | tcp_rcv_space_adjust(sk); | 4403 | tcp_rcv_space_adjust(sk); |
4404 | } | 4404 | } |
4405 | local_bh_disable(); | 4405 | local_bh_disable(); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 856f68466d49..02f583b3744a 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1994,7 +1994,6 @@ static void *listening_get_next(struct seq_file *seq, void *cur) | |||
1994 | } | 1994 | } |
1995 | req = req->dl_next; | 1995 | req = req->dl_next; |
1996 | } | 1996 | } |
1997 | st->offset = 0; | ||
1998 | if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries) | 1997 | if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries) |
1999 | break; | 1998 | break; |
2000 | get_req: | 1999 | get_req: |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index dc7c096ddfef..406f320336e6 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -1350,7 +1350,7 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, | |||
1350 | return 0; | 1350 | return 0; |
1351 | } | 1351 | } |
1352 | 1352 | ||
1353 | /* Intialize TSO state of a skb. | 1353 | /* Initialize TSO state of a skb. |
1354 | * This must be invoked the first time we consider transmitting | 1354 | * This must be invoked the first time we consider transmitting |
1355 | * SKB onto the wire. | 1355 | * SKB onto the wire. |
1356 | */ | 1356 | */ |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 24a1cf110d80..fd6782e3a038 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2661,14 +2661,12 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2661 | struct net *net = dev_net(dev); | 2661 | struct net *net = dev_net(dev); |
2662 | struct inet6_dev *idev; | 2662 | struct inet6_dev *idev; |
2663 | struct inet6_ifaddr *ifa; | 2663 | struct inet6_ifaddr *ifa; |
2664 | LIST_HEAD(keep_list); | 2664 | int state, i; |
2665 | int state; | ||
2666 | 2665 | ||
2667 | ASSERT_RTNL(); | 2666 | ASSERT_RTNL(); |
2668 | 2667 | ||
2669 | /* Flush routes if device is being removed or it is not loopback */ | 2668 | rt6_ifdown(net, dev); |
2670 | if (how || !(dev->flags & IFF_LOOPBACK)) | 2669 | neigh_ifdown(&nd_tbl, dev); |
2671 | rt6_ifdown(net, dev); | ||
2672 | 2670 | ||
2673 | idev = __in6_dev_get(dev); | 2671 | idev = __in6_dev_get(dev); |
2674 | if (idev == NULL) | 2672 | if (idev == NULL) |
@@ -2689,6 +2687,23 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2689 | 2687 | ||
2690 | } | 2688 | } |
2691 | 2689 | ||
2690 | /* Step 2: clear hash table */ | ||
2691 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { | ||
2692 | struct hlist_head *h = &inet6_addr_lst[i]; | ||
2693 | struct hlist_node *n; | ||
2694 | |||
2695 | spin_lock_bh(&addrconf_hash_lock); | ||
2696 | restart: | ||
2697 | hlist_for_each_entry_rcu(ifa, n, h, addr_lst) { | ||
2698 | if (ifa->idev == idev) { | ||
2699 | hlist_del_init_rcu(&ifa->addr_lst); | ||
2700 | addrconf_del_timer(ifa); | ||
2701 | goto restart; | ||
2702 | } | ||
2703 | } | ||
2704 | spin_unlock_bh(&addrconf_hash_lock); | ||
2705 | } | ||
2706 | |||
2692 | write_lock_bh(&idev->lock); | 2707 | write_lock_bh(&idev->lock); |
2693 | 2708 | ||
2694 | /* Step 2: clear flags for stateless addrconf */ | 2709 | /* Step 2: clear flags for stateless addrconf */ |
@@ -2722,52 +2737,23 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2722 | struct inet6_ifaddr, if_list); | 2737 | struct inet6_ifaddr, if_list); |
2723 | addrconf_del_timer(ifa); | 2738 | addrconf_del_timer(ifa); |
2724 | 2739 | ||
2725 | /* If just doing link down, and address is permanent | 2740 | list_del(&ifa->if_list); |
2726 | and not link-local, then retain it. */ | ||
2727 | if (!how && | ||
2728 | (ifa->flags&IFA_F_PERMANENT) && | ||
2729 | !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { | ||
2730 | list_move_tail(&ifa->if_list, &keep_list); | ||
2731 | |||
2732 | /* If not doing DAD on this address, just keep it. */ | ||
2733 | if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || | ||
2734 | idev->cnf.accept_dad <= 0 || | ||
2735 | (ifa->flags & IFA_F_NODAD)) | ||
2736 | continue; | ||
2737 | 2741 | ||
2738 | /* If it was tentative already, no need to notify */ | 2742 | write_unlock_bh(&idev->lock); |
2739 | if (ifa->flags & IFA_F_TENTATIVE) | ||
2740 | continue; | ||
2741 | 2743 | ||
2742 | /* Flag it for later restoration when link comes up */ | 2744 | spin_lock_bh(&ifa->state_lock); |
2743 | ifa->flags |= IFA_F_TENTATIVE; | 2745 | state = ifa->state; |
2744 | ifa->state = INET6_IFADDR_STATE_DAD; | 2746 | ifa->state = INET6_IFADDR_STATE_DEAD; |
2745 | } else { | 2747 | spin_unlock_bh(&ifa->state_lock); |
2746 | list_del(&ifa->if_list); | ||
2747 | |||
2748 | /* clear hash table */ | ||
2749 | spin_lock_bh(&addrconf_hash_lock); | ||
2750 | hlist_del_init_rcu(&ifa->addr_lst); | ||
2751 | spin_unlock_bh(&addrconf_hash_lock); | ||
2752 | |||
2753 | write_unlock_bh(&idev->lock); | ||
2754 | spin_lock_bh(&ifa->state_lock); | ||
2755 | state = ifa->state; | ||
2756 | ifa->state = INET6_IFADDR_STATE_DEAD; | ||
2757 | spin_unlock_bh(&ifa->state_lock); | ||
2758 | |||
2759 | if (state != INET6_IFADDR_STATE_DEAD) { | ||
2760 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | ||
2761 | atomic_notifier_call_chain(&inet6addr_chain, | ||
2762 | NETDEV_DOWN, ifa); | ||
2763 | } | ||
2764 | 2748 | ||
2765 | in6_ifa_put(ifa); | 2749 | if (state != INET6_IFADDR_STATE_DEAD) { |
2766 | write_lock_bh(&idev->lock); | 2750 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
2751 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); | ||
2767 | } | 2752 | } |
2768 | } | 2753 | in6_ifa_put(ifa); |
2769 | 2754 | ||
2770 | list_splice(&keep_list, &idev->addr_list); | 2755 | write_lock_bh(&idev->lock); |
2756 | } | ||
2771 | 2757 | ||
2772 | write_unlock_bh(&idev->lock); | 2758 | write_unlock_bh(&idev->lock); |
2773 | 2759 | ||
@@ -4156,8 +4142,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4156 | addrconf_leave_solict(ifp->idev, &ifp->addr); | 4142 | addrconf_leave_solict(ifp->idev, &ifp->addr); |
4157 | dst_hold(&ifp->rt->dst); | 4143 | dst_hold(&ifp->rt->dst); |
4158 | 4144 | ||
4159 | if (ifp->state == INET6_IFADDR_STATE_DEAD && | 4145 | if (ip6_del_rt(ifp->rt)) |
4160 | ip6_del_rt(ifp->rt)) | ||
4161 | dst_free(&ifp->rt->dst); | 4146 | dst_free(&ifp->rt->dst); |
4162 | break; | 4147 | break; |
4163 | } | 4148 | } |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 059a3de647db..978e80e2c4a8 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -300,7 +300,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
300 | goto out; | 300 | goto out; |
301 | } | 301 | } |
302 | 302 | ||
303 | /* Reproduce AF_INET checks to make the bindings consitant */ | 303 | /* Reproduce AF_INET checks to make the bindings consistent */ |
304 | v4addr = addr->sin6_addr.s6_addr32[3]; | 304 | v4addr = addr->sin6_addr.s6_addr32[3]; |
305 | chk_addr_ret = inet_addr_type(net, v4addr); | 305 | chk_addr_ret = inet_addr_type(net, v4addr); |
306 | if (!sysctl_ip_nonlocal_bind && | 306 | if (!sysctl_ip_nonlocal_bind && |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 373bd0416f69..1c29f95695de 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -72,8 +72,6 @@ | |||
72 | #define RT6_TRACE(x...) do { ; } while (0) | 72 | #define RT6_TRACE(x...) do { ; } while (0) |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | #define CLONE_OFFLINK_ROUTE 0 | ||
76 | |||
77 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); | 75 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort); |
78 | static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); | 76 | static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); |
79 | static unsigned int ip6_default_advmss(const struct dst_entry *dst); | 77 | static unsigned int ip6_default_advmss(const struct dst_entry *dst); |
@@ -115,6 +113,11 @@ static struct dst_ops ip6_dst_ops_template = { | |||
115 | .local_out = __ip6_local_out, | 113 | .local_out = __ip6_local_out, |
116 | }; | 114 | }; |
117 | 115 | ||
116 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) | ||
117 | { | ||
118 | return 0; | ||
119 | } | ||
120 | |||
118 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 121 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
119 | { | 122 | { |
120 | } | 123 | } |
@@ -124,6 +127,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
124 | .protocol = cpu_to_be16(ETH_P_IPV6), | 127 | .protocol = cpu_to_be16(ETH_P_IPV6), |
125 | .destroy = ip6_dst_destroy, | 128 | .destroy = ip6_dst_destroy, |
126 | .check = ip6_dst_check, | 129 | .check = ip6_dst_check, |
130 | .default_mtu = ip6_blackhole_default_mtu, | ||
127 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 131 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
128 | }; | 132 | }; |
129 | 133 | ||
@@ -196,7 +200,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) | |||
196 | in6_dev_put(idev); | 200 | in6_dev_put(idev); |
197 | } | 201 | } |
198 | if (peer) { | 202 | if (peer) { |
199 | BUG_ON(!(rt->rt6i_flags & RTF_CACHE)); | ||
200 | rt->rt6i_peer = NULL; | 203 | rt->rt6i_peer = NULL; |
201 | inet_putpeer(peer); | 204 | inet_putpeer(peer); |
202 | } | 205 | } |
@@ -206,9 +209,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create) | |||
206 | { | 209 | { |
207 | struct inet_peer *peer; | 210 | struct inet_peer *peer; |
208 | 211 | ||
209 | if (WARN_ON(!(rt->rt6i_flags & RTF_CACHE))) | ||
210 | return; | ||
211 | |||
212 | peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); | 212 | peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); |
213 | if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) | 213 | if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) |
214 | inet_putpeer(peer); | 214 | inet_putpeer(peer); |
@@ -738,13 +738,8 @@ restart: | |||
738 | 738 | ||
739 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 739 | if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
740 | nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); | 740 | nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); |
741 | else { | 741 | else |
742 | #if CLONE_OFFLINK_ROUTE | ||
743 | nrt = rt6_alloc_clone(rt, &fl->fl6_dst); | 742 | nrt = rt6_alloc_clone(rt, &fl->fl6_dst); |
744 | #else | ||
745 | goto out2; | ||
746 | #endif | ||
747 | } | ||
748 | 743 | ||
749 | dst_release(&rt->dst); | 744 | dst_release(&rt->dst); |
750 | rt = nrt ? : net->ipv6.ip6_null_entry; | 745 | rt = nrt ? : net->ipv6.ip6_null_entry; |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index fa1d8f4e0051..7cb65ef79f9c 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <net/addrconf.h> | 15 | #include <net/addrconf.h> |
16 | #include <net/inet_frag.h> | 16 | #include <net/inet_frag.h> |
17 | 17 | ||
18 | static struct ctl_table empty[1]; | ||
19 | |||
18 | static ctl_table ipv6_table_template[] = { | 20 | static ctl_table ipv6_table_template[] = { |
19 | { | 21 | { |
20 | .procname = "route", | 22 | .procname = "route", |
@@ -35,6 +37,12 @@ static ctl_table ipv6_table_template[] = { | |||
35 | .mode = 0644, | 37 | .mode = 0644, |
36 | .proc_handler = proc_dointvec | 38 | .proc_handler = proc_dointvec |
37 | }, | 39 | }, |
40 | { | ||
41 | .procname = "neigh", | ||
42 | .maxlen = 0, | ||
43 | .mode = 0555, | ||
44 | .child = empty, | ||
45 | }, | ||
38 | { } | 46 | { } |
39 | }; | 47 | }; |
40 | 48 | ||
@@ -152,7 +160,6 @@ static struct ctl_table_header *ip6_base; | |||
152 | 160 | ||
153 | int ipv6_static_sysctl_register(void) | 161 | int ipv6_static_sysctl_register(void) |
154 | { | 162 | { |
155 | static struct ctl_table empty[1]; | ||
156 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); | 163 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); |
157 | if (ip6_base == NULL) | 164 | if (ip6_base == NULL) |
158 | return -ENOMEM; | 165 | return -ENOMEM; |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 7e74023ea6e4..da87428681cc 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -98,6 +98,10 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
98 | if (!xdst->u.rt6.rt6i_idev) | 98 | if (!xdst->u.rt6.rt6i_idev) |
99 | return -ENODEV; | 99 | return -ENODEV; |
100 | 100 | ||
101 | xdst->u.rt6.rt6i_peer = rt->rt6i_peer; | ||
102 | if (rt->rt6i_peer) | ||
103 | atomic_inc(&rt->rt6i_peer->refcnt); | ||
104 | |||
101 | /* Sheit... I remember I did this right. Apparently, | 105 | /* Sheit... I remember I did this right. Apparently, |
102 | * it was magically lost, so this code needs audit */ | 106 | * it was magically lost, so this code needs audit */ |
103 | xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST | | 107 | xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST | |
@@ -216,6 +220,8 @@ static void xfrm6_dst_destroy(struct dst_entry *dst) | |||
216 | 220 | ||
217 | if (likely(xdst->u.rt6.rt6i_idev)) | 221 | if (likely(xdst->u.rt6.rt6i_idev)) |
218 | in6_dev_put(xdst->u.rt6.rt6i_idev); | 222 | in6_dev_put(xdst->u.rt6.rt6i_idev); |
223 | if (likely(xdst->u.rt6.rt6i_peer)) | ||
224 | inet_putpeer(xdst->u.rt6.rt6i_peer); | ||
219 | xfrm_dst_destroy(xdst); | 225 | xfrm_dst_destroy(xdst); |
220 | } | 226 | } |
221 | 227 | ||
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 9109262abd24..c766056d0488 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -20,7 +20,7 @@ config MAC80211_HAS_RC | |||
20 | def_bool n | 20 | def_bool n |
21 | 21 | ||
22 | config MAC80211_RC_PID | 22 | config MAC80211_RC_PID |
23 | bool "PID controller based rate control algorithm" if EMBEDDED | 23 | bool "PID controller based rate control algorithm" if EXPERT |
24 | select MAC80211_HAS_RC | 24 | select MAC80211_HAS_RC |
25 | ---help--- | 25 | ---help--- |
26 | This option enables a TX rate control algorithm for | 26 | This option enables a TX rate control algorithm for |
@@ -28,14 +28,14 @@ config MAC80211_RC_PID | |||
28 | rate. | 28 | rate. |
29 | 29 | ||
30 | config MAC80211_RC_MINSTREL | 30 | config MAC80211_RC_MINSTREL |
31 | bool "Minstrel" if EMBEDDED | 31 | bool "Minstrel" if EXPERT |
32 | select MAC80211_HAS_RC | 32 | select MAC80211_HAS_RC |
33 | default y | 33 | default y |
34 | ---help--- | 34 | ---help--- |
35 | This option enables the 'minstrel' TX rate control algorithm | 35 | This option enables the 'minstrel' TX rate control algorithm |
36 | 36 | ||
37 | config MAC80211_RC_MINSTREL_HT | 37 | config MAC80211_RC_MINSTREL_HT |
38 | bool "Minstrel 802.11n support" if EMBEDDED | 38 | bool "Minstrel 802.11n support" if EXPERT |
39 | depends on MAC80211_RC_MINSTREL | 39 | depends on MAC80211_RC_MINSTREL |
40 | default y | 40 | default y |
41 | ---help--- | 41 | ---help--- |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 5950e3abead9..b64b42bc774b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2230,6 +2230,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2230 | 2230 | ||
2231 | sdata = vif_to_sdata(vif); | 2231 | sdata = vif_to_sdata(vif); |
2232 | 2232 | ||
2233 | if (!ieee80211_sdata_running(sdata)) | ||
2234 | goto out; | ||
2235 | |||
2233 | if (tim_offset) | 2236 | if (tim_offset) |
2234 | *tim_offset = 0; | 2237 | *tim_offset = 0; |
2235 | if (tim_length) | 2238 | if (tim_length) |
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index eaf765876458..7fce6dfd2180 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig | |||
@@ -18,7 +18,7 @@ config RFKILL_LEDS | |||
18 | default y | 18 | default y |
19 | 19 | ||
20 | config RFKILL_INPUT | 20 | config RFKILL_INPUT |
21 | bool "RF switch input support" if EMBEDDED | 21 | bool "RF switch input support" if EXPERT |
22 | depends on RFKILL | 22 | depends on RFKILL |
23 | depends on INPUT = y || RFKILL = INPUT | 23 | depends on INPUT = y || RFKILL = INPUT |
24 | default y if !EMBEDDED | 24 | default y if !EXPERT |
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 0b9bb2085ce4..74c064c0dfdd 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
@@ -808,7 +808,7 @@ static int __init af_rxrpc_init(void) | |||
808 | goto error_call_jar; | 808 | goto error_call_jar; |
809 | } | 809 | } |
810 | 810 | ||
811 | rxrpc_workqueue = create_workqueue("krxrpcd"); | 811 | rxrpc_workqueue = alloc_workqueue("krxrpcd", 0, 1); |
812 | if (!rxrpc_workqueue) { | 812 | if (!rxrpc_workqueue) { |
813 | printk(KERN_NOTICE "RxRPC: Failed to allocate work queue\n"); | 813 | printk(KERN_NOTICE "RxRPC: Failed to allocate work queue\n"); |
814 | goto error_work_queue; | 814 | goto error_work_queue; |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index a36270a994d7..f04d4a484d53 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -24,7 +24,7 @@ menuconfig NET_SCHED | |||
24 | To administer these schedulers, you'll need the user-level utilities | 24 | To administer these schedulers, you'll need the user-level utilities |
25 | from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>. | 25 | from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>. |
26 | That package also contains some documentation; for more, check out | 26 | That package also contains some documentation; for more, check out |
27 | <http://linux-net.osdl.org/index.php/Iproute2>. | 27 | <http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2>. |
28 | 28 | ||
29 | This Quality of Service (QoS) support will enable you to use | 29 | This Quality of Service (QoS) support will enable you to use |
30 | Differentiated Services (diffserv) and Resource Reservation Protocol | 30 | Differentiated Services (diffserv) and Resource Reservation Protocol |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index c80d1c210c5d..5f63ec58942c 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -390,7 +390,6 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
390 | ret = qdisc_enqueue(skb, cl->q); | 390 | ret = qdisc_enqueue(skb, cl->q); |
391 | if (ret == NET_XMIT_SUCCESS) { | 391 | if (ret == NET_XMIT_SUCCESS) { |
392 | sch->q.qlen++; | 392 | sch->q.qlen++; |
393 | qdisc_bstats_update(sch, skb); | ||
394 | cbq_mark_toplevel(q, cl); | 393 | cbq_mark_toplevel(q, cl); |
395 | if (!cl->next_alive) | 394 | if (!cl->next_alive) |
396 | cbq_activate_class(cl); | 395 | cbq_activate_class(cl); |
@@ -649,7 +648,6 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child) | |||
649 | ret = qdisc_enqueue(skb, cl->q); | 648 | ret = qdisc_enqueue(skb, cl->q); |
650 | if (ret == NET_XMIT_SUCCESS) { | 649 | if (ret == NET_XMIT_SUCCESS) { |
651 | sch->q.qlen++; | 650 | sch->q.qlen++; |
652 | qdisc_bstats_update(sch, skb); | ||
653 | if (!cl->next_alive) | 651 | if (!cl->next_alive) |
654 | cbq_activate_class(cl); | 652 | cbq_activate_class(cl); |
655 | return 0; | 653 | return 0; |
@@ -971,6 +969,7 @@ cbq_dequeue(struct Qdisc *sch) | |||
971 | 969 | ||
972 | skb = cbq_dequeue_1(sch); | 970 | skb = cbq_dequeue_1(sch); |
973 | if (skb) { | 971 | if (skb) { |
972 | qdisc_bstats_update(sch, skb); | ||
974 | sch->q.qlen--; | 973 | sch->q.qlen--; |
975 | sch->flags &= ~TCQ_F_THROTTLED; | 974 | sch->flags &= ~TCQ_F_THROTTLED; |
976 | return skb; | 975 | return skb; |
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index de55e642eafc..6b7fe4a84f13 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c | |||
@@ -376,7 +376,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
376 | } | 376 | } |
377 | 377 | ||
378 | bstats_update(&cl->bstats, skb); | 378 | bstats_update(&cl->bstats, skb); |
379 | qdisc_bstats_update(sch, skb); | ||
380 | 379 | ||
381 | sch->q.qlen++; | 380 | sch->q.qlen++; |
382 | return err; | 381 | return err; |
@@ -403,6 +402,7 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch) | |||
403 | skb = qdisc_dequeue_peeked(cl->qdisc); | 402 | skb = qdisc_dequeue_peeked(cl->qdisc); |
404 | if (cl->qdisc->q.qlen == 0) | 403 | if (cl->qdisc->q.qlen == 0) |
405 | list_del(&cl->alist); | 404 | list_del(&cl->alist); |
405 | qdisc_bstats_update(sch, skb); | ||
406 | sch->q.qlen--; | 406 | sch->q.qlen--; |
407 | return skb; | 407 | return skb; |
408 | } | 408 | } |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 60f4bdd4408e..0f7bf3fdfea5 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -260,7 +260,6 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
260 | return err; | 260 | return err; |
261 | } | 261 | } |
262 | 262 | ||
263 | qdisc_bstats_update(sch, skb); | ||
264 | sch->q.qlen++; | 263 | sch->q.qlen++; |
265 | 264 | ||
266 | return NET_XMIT_SUCCESS; | 265 | return NET_XMIT_SUCCESS; |
@@ -283,6 +282,7 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch) | |||
283 | if (skb == NULL) | 282 | if (skb == NULL) |
284 | return NULL; | 283 | return NULL; |
285 | 284 | ||
285 | qdisc_bstats_update(sch, skb); | ||
286 | sch->q.qlen--; | 286 | sch->q.qlen--; |
287 | 287 | ||
288 | index = skb->tc_index & (p->indices - 1); | 288 | index = skb->tc_index & (p->indices - 1); |
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index aa4d6337e43c..d468b479aa93 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c | |||
@@ -46,17 +46,14 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
46 | 46 | ||
47 | static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) | 47 | static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) |
48 | { | 48 | { |
49 | struct sk_buff *skb_head; | ||
50 | struct fifo_sched_data *q = qdisc_priv(sch); | 49 | struct fifo_sched_data *q = qdisc_priv(sch); |
51 | 50 | ||
52 | if (likely(skb_queue_len(&sch->q) < q->limit)) | 51 | if (likely(skb_queue_len(&sch->q) < q->limit)) |
53 | return qdisc_enqueue_tail(skb, sch); | 52 | return qdisc_enqueue_tail(skb, sch); |
54 | 53 | ||
55 | /* queue full, remove one skb to fulfill the limit */ | 54 | /* queue full, remove one skb to fulfill the limit */ |
56 | skb_head = qdisc_dequeue_head(sch); | 55 | __qdisc_queue_drop_head(sch, &sch->q); |
57 | sch->qstats.drops++; | 56 | sch->qstats.drops++; |
58 | kfree_skb(skb_head); | ||
59 | |||
60 | qdisc_enqueue_tail(skb, sch); | 57 | qdisc_enqueue_tail(skb, sch); |
61 | 58 | ||
62 | return NET_XMIT_CN; | 59 | return NET_XMIT_CN; |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 2e45791d4f6c..14a799de1c35 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -1600,7 +1600,6 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
1600 | set_active(cl, qdisc_pkt_len(skb)); | 1600 | set_active(cl, qdisc_pkt_len(skb)); |
1601 | 1601 | ||
1602 | bstats_update(&cl->bstats, skb); | 1602 | bstats_update(&cl->bstats, skb); |
1603 | qdisc_bstats_update(sch, skb); | ||
1604 | sch->q.qlen++; | 1603 | sch->q.qlen++; |
1605 | 1604 | ||
1606 | return NET_XMIT_SUCCESS; | 1605 | return NET_XMIT_SUCCESS; |
@@ -1666,6 +1665,7 @@ hfsc_dequeue(struct Qdisc *sch) | |||
1666 | } | 1665 | } |
1667 | 1666 | ||
1668 | sch->flags &= ~TCQ_F_THROTTLED; | 1667 | sch->flags &= ~TCQ_F_THROTTLED; |
1668 | qdisc_bstats_update(sch, skb); | ||
1669 | sch->q.qlen--; | 1669 | sch->q.qlen--; |
1670 | 1670 | ||
1671 | return skb; | 1671 | return skb; |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 984c1b0c6836..fc12fe6f5597 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -574,7 +574,6 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
574 | } | 574 | } |
575 | 575 | ||
576 | sch->q.qlen++; | 576 | sch->q.qlen++; |
577 | qdisc_bstats_update(sch, skb); | ||
578 | return NET_XMIT_SUCCESS; | 577 | return NET_XMIT_SUCCESS; |
579 | } | 578 | } |
580 | 579 | ||
@@ -842,7 +841,7 @@ next: | |||
842 | 841 | ||
843 | static struct sk_buff *htb_dequeue(struct Qdisc *sch) | 842 | static struct sk_buff *htb_dequeue(struct Qdisc *sch) |
844 | { | 843 | { |
845 | struct sk_buff *skb = NULL; | 844 | struct sk_buff *skb; |
846 | struct htb_sched *q = qdisc_priv(sch); | 845 | struct htb_sched *q = qdisc_priv(sch); |
847 | int level; | 846 | int level; |
848 | psched_time_t next_event; | 847 | psched_time_t next_event; |
@@ -851,6 +850,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
851 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ | 850 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ |
852 | skb = __skb_dequeue(&q->direct_queue); | 851 | skb = __skb_dequeue(&q->direct_queue); |
853 | if (skb != NULL) { | 852 | if (skb != NULL) { |
853 | ok: | ||
854 | qdisc_bstats_update(sch, skb); | ||
854 | sch->flags &= ~TCQ_F_THROTTLED; | 855 | sch->flags &= ~TCQ_F_THROTTLED; |
855 | sch->q.qlen--; | 856 | sch->q.qlen--; |
856 | return skb; | 857 | return skb; |
@@ -884,11 +885,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
884 | int prio = ffz(m); | 885 | int prio = ffz(m); |
885 | m |= 1 << prio; | 886 | m |= 1 << prio; |
886 | skb = htb_dequeue_tree(q, prio, level); | 887 | skb = htb_dequeue_tree(q, prio, level); |
887 | if (likely(skb != NULL)) { | 888 | if (likely(skb != NULL)) |
888 | sch->q.qlen--; | 889 | goto ok; |
889 | sch->flags &= ~TCQ_F_THROTTLED; | ||
890 | goto fin; | ||
891 | } | ||
892 | } | 890 | } |
893 | } | 891 | } |
894 | sch->qstats.overlimits++; | 892 | sch->qstats.overlimits++; |
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 21f13da24763..436a2e75b322 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c | |||
@@ -83,7 +83,6 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
83 | 83 | ||
84 | ret = qdisc_enqueue(skb, qdisc); | 84 | ret = qdisc_enqueue(skb, qdisc); |
85 | if (ret == NET_XMIT_SUCCESS) { | 85 | if (ret == NET_XMIT_SUCCESS) { |
86 | qdisc_bstats_update(sch, skb); | ||
87 | sch->q.qlen++; | 86 | sch->q.qlen++; |
88 | return NET_XMIT_SUCCESS; | 87 | return NET_XMIT_SUCCESS; |
89 | } | 88 | } |
@@ -112,6 +111,7 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch) | |||
112 | qdisc = q->queues[q->curband]; | 111 | qdisc = q->queues[q->curband]; |
113 | skb = qdisc->dequeue(qdisc); | 112 | skb = qdisc->dequeue(qdisc); |
114 | if (skb) { | 113 | if (skb) { |
114 | qdisc_bstats_update(sch, skb); | ||
115 | sch->q.qlen--; | 115 | sch->q.qlen--; |
116 | return skb; | 116 | return skb; |
117 | } | 117 | } |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 1c4bce863479..6a3006b38dc5 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -240,7 +240,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
240 | 240 | ||
241 | if (likely(ret == NET_XMIT_SUCCESS)) { | 241 | if (likely(ret == NET_XMIT_SUCCESS)) { |
242 | sch->q.qlen++; | 242 | sch->q.qlen++; |
243 | qdisc_bstats_update(sch, skb); | ||
244 | } else if (net_xmit_drop_count(ret)) { | 243 | } else if (net_xmit_drop_count(ret)) { |
245 | sch->qstats.drops++; | 244 | sch->qstats.drops++; |
246 | } | 245 | } |
@@ -289,6 +288,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch) | |||
289 | skb->tstamp.tv64 = 0; | 288 | skb->tstamp.tv64 = 0; |
290 | #endif | 289 | #endif |
291 | pr_debug("netem_dequeue: return skb=%p\n", skb); | 290 | pr_debug("netem_dequeue: return skb=%p\n", skb); |
291 | qdisc_bstats_update(sch, skb); | ||
292 | sch->q.qlen--; | 292 | sch->q.qlen--; |
293 | return skb; | 293 | return skb; |
294 | } | 294 | } |
@@ -476,7 +476,6 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) | |||
476 | __skb_queue_after(list, skb, nskb); | 476 | __skb_queue_after(list, skb, nskb); |
477 | 477 | ||
478 | sch->qstats.backlog += qdisc_pkt_len(nskb); | 478 | sch->qstats.backlog += qdisc_pkt_len(nskb); |
479 | qdisc_bstats_update(sch, nskb); | ||
480 | 479 | ||
481 | return NET_XMIT_SUCCESS; | 480 | return NET_XMIT_SUCCESS; |
482 | } | 481 | } |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 966158d49dd1..fbd710d619bf 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -84,7 +84,6 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
84 | 84 | ||
85 | ret = qdisc_enqueue(skb, qdisc); | 85 | ret = qdisc_enqueue(skb, qdisc); |
86 | if (ret == NET_XMIT_SUCCESS) { | 86 | if (ret == NET_XMIT_SUCCESS) { |
87 | qdisc_bstats_update(sch, skb); | ||
88 | sch->q.qlen++; | 87 | sch->q.qlen++; |
89 | return NET_XMIT_SUCCESS; | 88 | return NET_XMIT_SUCCESS; |
90 | } | 89 | } |
@@ -116,6 +115,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc* sch) | |||
116 | struct Qdisc *qdisc = q->queues[prio]; | 115 | struct Qdisc *qdisc = q->queues[prio]; |
117 | struct sk_buff *skb = qdisc->dequeue(qdisc); | 116 | struct sk_buff *skb = qdisc->dequeue(qdisc); |
118 | if (skb) { | 117 | if (skb) { |
118 | qdisc_bstats_update(sch, skb); | ||
119 | sch->q.qlen--; | 119 | sch->q.qlen--; |
120 | return skb; | 120 | return skb; |
121 | } | 121 | } |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index a6009c5a2c97..9f98dbd32d4c 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -94,7 +94,6 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
94 | 94 | ||
95 | ret = qdisc_enqueue(skb, child); | 95 | ret = qdisc_enqueue(skb, child); |
96 | if (likely(ret == NET_XMIT_SUCCESS)) { | 96 | if (likely(ret == NET_XMIT_SUCCESS)) { |
97 | qdisc_bstats_update(sch, skb); | ||
98 | sch->q.qlen++; | 97 | sch->q.qlen++; |
99 | } else if (net_xmit_drop_count(ret)) { | 98 | } else if (net_xmit_drop_count(ret)) { |
100 | q->stats.pdrop++; | 99 | q->stats.pdrop++; |
@@ -114,11 +113,13 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch) | |||
114 | struct Qdisc *child = q->qdisc; | 113 | struct Qdisc *child = q->qdisc; |
115 | 114 | ||
116 | skb = child->dequeue(child); | 115 | skb = child->dequeue(child); |
117 | if (skb) | 116 | if (skb) { |
117 | qdisc_bstats_update(sch, skb); | ||
118 | sch->q.qlen--; | 118 | sch->q.qlen--; |
119 | else if (!red_is_idling(&q->parms)) | 119 | } else { |
120 | red_start_of_idle_period(&q->parms); | 120 | if (!red_is_idling(&q->parms)) |
121 | 121 | red_start_of_idle_period(&q->parms); | |
122 | } | ||
122 | return skb; | 123 | return skb; |
123 | } | 124 | } |
124 | 125 | ||
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 239ec53a634d..edea8cefec6c 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -402,10 +402,8 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
402 | q->tail = slot; | 402 | q->tail = slot; |
403 | slot->allot = q->scaled_quantum; | 403 | slot->allot = q->scaled_quantum; |
404 | } | 404 | } |
405 | if (++sch->q.qlen <= q->limit) { | 405 | if (++sch->q.qlen <= q->limit) |
406 | qdisc_bstats_update(sch, skb); | ||
407 | return NET_XMIT_SUCCESS; | 406 | return NET_XMIT_SUCCESS; |
408 | } | ||
409 | 407 | ||
410 | sfq_drop(sch); | 408 | sfq_drop(sch); |
411 | return NET_XMIT_CN; | 409 | return NET_XMIT_CN; |
@@ -445,6 +443,7 @@ next_slot: | |||
445 | } | 443 | } |
446 | skb = slot_dequeue_head(slot); | 444 | skb = slot_dequeue_head(slot); |
447 | sfq_dec(q, a); | 445 | sfq_dec(q, a); |
446 | qdisc_bstats_update(sch, skb); | ||
448 | sch->q.qlen--; | 447 | sch->q.qlen--; |
449 | sch->qstats.backlog -= qdisc_pkt_len(skb); | 448 | sch->qstats.backlog -= qdisc_pkt_len(skb); |
450 | 449 | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 77565e721811..e93165820c3f 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -134,7 +134,6 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | sch->q.qlen++; | 136 | sch->q.qlen++; |
137 | qdisc_bstats_update(sch, skb); | ||
138 | return NET_XMIT_SUCCESS; | 137 | return NET_XMIT_SUCCESS; |
139 | } | 138 | } |
140 | 139 | ||
@@ -187,6 +186,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) | |||
187 | q->ptokens = ptoks; | 186 | q->ptokens = ptoks; |
188 | sch->q.qlen--; | 187 | sch->q.qlen--; |
189 | sch->flags &= ~TCQ_F_THROTTLED; | 188 | sch->flags &= ~TCQ_F_THROTTLED; |
189 | qdisc_bstats_update(sch, skb); | ||
190 | return skb; | 190 | return skb; |
191 | } | 191 | } |
192 | 192 | ||
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 84ce48eadff4..d84e7329660f 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -87,7 +87,6 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
87 | 87 | ||
88 | if (q->q.qlen < dev->tx_queue_len) { | 88 | if (q->q.qlen < dev->tx_queue_len) { |
89 | __skb_queue_tail(&q->q, skb); | 89 | __skb_queue_tail(&q->q, skb); |
90 | qdisc_bstats_update(sch, skb); | ||
91 | return NET_XMIT_SUCCESS; | 90 | return NET_XMIT_SUCCESS; |
92 | } | 91 | } |
93 | 92 | ||
@@ -111,6 +110,8 @@ teql_dequeue(struct Qdisc* sch) | |||
111 | dat->m->slaves = sch; | 110 | dat->m->slaves = sch; |
112 | netif_wake_queue(m); | 111 | netif_wake_queue(m); |
113 | } | 112 | } |
113 | } else { | ||
114 | qdisc_bstats_update(sch, skb); | ||
114 | } | 115 | } |
115 | sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen; | 116 | sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen; |
116 | return skb; | 117 | return skb; |
diff --git a/net/socket.c b/net/socket.c index ccc576a6a508..ac2219f90d5d 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -306,20 +306,6 @@ static const struct super_operations sockfs_ops = { | |||
306 | .statfs = simple_statfs, | 306 | .statfs = simple_statfs, |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static struct dentry *sockfs_mount(struct file_system_type *fs_type, | ||
310 | int flags, const char *dev_name, void *data) | ||
311 | { | ||
312 | return mount_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC); | ||
313 | } | ||
314 | |||
315 | static struct vfsmount *sock_mnt __read_mostly; | ||
316 | |||
317 | static struct file_system_type sock_fs_type = { | ||
318 | .name = "sockfs", | ||
319 | .mount = sockfs_mount, | ||
320 | .kill_sb = kill_anon_super, | ||
321 | }; | ||
322 | |||
323 | /* | 309 | /* |
324 | * sockfs_dname() is called from d_path(). | 310 | * sockfs_dname() is called from d_path(). |
325 | */ | 311 | */ |
@@ -333,6 +319,21 @@ static const struct dentry_operations sockfs_dentry_operations = { | |||
333 | .d_dname = sockfs_dname, | 319 | .d_dname = sockfs_dname, |
334 | }; | 320 | }; |
335 | 321 | ||
322 | static struct dentry *sockfs_mount(struct file_system_type *fs_type, | ||
323 | int flags, const char *dev_name, void *data) | ||
324 | { | ||
325 | return mount_pseudo(fs_type, "socket:", &sockfs_ops, | ||
326 | &sockfs_dentry_operations, SOCKFS_MAGIC); | ||
327 | } | ||
328 | |||
329 | static struct vfsmount *sock_mnt __read_mostly; | ||
330 | |||
331 | static struct file_system_type sock_fs_type = { | ||
332 | .name = "sockfs", | ||
333 | .mount = sockfs_mount, | ||
334 | .kill_sb = kill_anon_super, | ||
335 | }; | ||
336 | |||
336 | /* | 337 | /* |
337 | * Obtains the first available file descriptor and sets it up for use. | 338 | * Obtains the first available file descriptor and sets it up for use. |
338 | * | 339 | * |
@@ -368,7 +369,6 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags) | |||
368 | } | 369 | } |
369 | path.mnt = mntget(sock_mnt); | 370 | path.mnt = mntget(sock_mnt); |
370 | 371 | ||
371 | d_set_d_op(path.dentry, &sockfs_dentry_operations); | ||
372 | d_instantiate(path.dentry, SOCK_INODE(sock)); | 372 | d_instantiate(path.dentry, SOCK_INODE(sock)); |
373 | SOCK_INODE(sock)->i_fop = &socket_file_ops; | 373 | SOCK_INODE(sock)->i_fop = &socket_file_ops; |
374 | 374 | ||
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index afe67849269f..67e31276682a 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
@@ -563,8 +563,17 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p) | |||
563 | return cred->cr_ops->crvalidate(task, p); | 563 | return cred->cr_ops->crvalidate(task, p); |
564 | } | 564 | } |
565 | 565 | ||
566 | static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, | ||
567 | __be32 *data, void *obj) | ||
568 | { | ||
569 | struct xdr_stream xdr; | ||
570 | |||
571 | xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data); | ||
572 | encode(rqstp, &xdr, obj); | ||
573 | } | ||
574 | |||
566 | int | 575 | int |
567 | rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, | 576 | rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, |
568 | __be32 *data, void *obj) | 577 | __be32 *data, void *obj) |
569 | { | 578 | { |
570 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 579 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
@@ -574,11 +583,22 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, | |||
574 | if (cred->cr_ops->crwrap_req) | 583 | if (cred->cr_ops->crwrap_req) |
575 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); | 584 | return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); |
576 | /* By default, we encode the arguments normally. */ | 585 | /* By default, we encode the arguments normally. */ |
577 | return encode(rqstp, data, obj); | 586 | rpcauth_wrap_req_encode(encode, rqstp, data, obj); |
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int | ||
591 | rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, | ||
592 | __be32 *data, void *obj) | ||
593 | { | ||
594 | struct xdr_stream xdr; | ||
595 | |||
596 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data); | ||
597 | return decode(rqstp, &xdr, obj); | ||
578 | } | 598 | } |
579 | 599 | ||
580 | int | 600 | int |
581 | rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | 601 | rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, |
582 | __be32 *data, void *obj) | 602 | __be32 *data, void *obj) |
583 | { | 603 | { |
584 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 604 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
@@ -589,7 +609,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, | |||
589 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, | 609 | return cred->cr_ops->crunwrap_resp(task, decode, rqstp, |
590 | data, obj); | 610 | data, obj); |
591 | /* By default, we decode the arguments normally. */ | 611 | /* By default, we decode the arguments normally. */ |
592 | return decode(rqstp, data, obj); | 612 | return rpcauth_unwrap_req_decode(decode, rqstp, data, obj); |
593 | } | 613 | } |
594 | 614 | ||
595 | int | 615 | int |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 3835ce35e224..45dbf1521b9a 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1231,9 +1231,19 @@ out_bad: | |||
1231 | return NULL; | 1231 | return NULL; |
1232 | } | 1232 | } |
1233 | 1233 | ||
1234 | static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, | ||
1235 | __be32 *p, void *obj) | ||
1236 | { | ||
1237 | struct xdr_stream xdr; | ||
1238 | |||
1239 | xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p); | ||
1240 | encode(rqstp, &xdr, obj); | ||
1241 | } | ||
1242 | |||
1234 | static inline int | 1243 | static inline int |
1235 | gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | 1244 | gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, |
1236 | kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) | 1245 | kxdreproc_t encode, struct rpc_rqst *rqstp, |
1246 | __be32 *p, void *obj) | ||
1237 | { | 1247 | { |
1238 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; | 1248 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; |
1239 | struct xdr_buf integ_buf; | 1249 | struct xdr_buf integ_buf; |
@@ -1249,9 +1259,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1249 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1259 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1250 | *p++ = htonl(rqstp->rq_seqno); | 1260 | *p++ = htonl(rqstp->rq_seqno); |
1251 | 1261 | ||
1252 | status = encode(rqstp, p, obj); | 1262 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1253 | if (status) | ||
1254 | return status; | ||
1255 | 1263 | ||
1256 | if (xdr_buf_subsegment(snd_buf, &integ_buf, | 1264 | if (xdr_buf_subsegment(snd_buf, &integ_buf, |
1257 | offset, snd_buf->len - offset)) | 1265 | offset, snd_buf->len - offset)) |
@@ -1325,7 +1333,8 @@ out: | |||
1325 | 1333 | ||
1326 | static inline int | 1334 | static inline int |
1327 | gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | 1335 | gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, |
1328 | kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) | 1336 | kxdreproc_t encode, struct rpc_rqst *rqstp, |
1337 | __be32 *p, void *obj) | ||
1329 | { | 1338 | { |
1330 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; | 1339 | struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; |
1331 | u32 offset; | 1340 | u32 offset; |
@@ -1342,9 +1351,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1342 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; | 1351 | offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; |
1343 | *p++ = htonl(rqstp->rq_seqno); | 1352 | *p++ = htonl(rqstp->rq_seqno); |
1344 | 1353 | ||
1345 | status = encode(rqstp, p, obj); | 1354 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1346 | if (status) | ||
1347 | return status; | ||
1348 | 1355 | ||
1349 | status = alloc_enc_pages(rqstp); | 1356 | status = alloc_enc_pages(rqstp); |
1350 | if (status) | 1357 | if (status) |
@@ -1394,7 +1401,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1394 | 1401 | ||
1395 | static int | 1402 | static int |
1396 | gss_wrap_req(struct rpc_task *task, | 1403 | gss_wrap_req(struct rpc_task *task, |
1397 | kxdrproc_t encode, void *rqstp, __be32 *p, void *obj) | 1404 | kxdreproc_t encode, void *rqstp, __be32 *p, void *obj) |
1398 | { | 1405 | { |
1399 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 1406 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
1400 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, | 1407 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, |
@@ -1407,12 +1414,14 @@ gss_wrap_req(struct rpc_task *task, | |||
1407 | /* The spec seems a little ambiguous here, but I think that not | 1414 | /* The spec seems a little ambiguous here, but I think that not |
1408 | * wrapping context destruction requests makes the most sense. | 1415 | * wrapping context destruction requests makes the most sense. |
1409 | */ | 1416 | */ |
1410 | status = encode(rqstp, p, obj); | 1417 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1418 | status = 0; | ||
1411 | goto out; | 1419 | goto out; |
1412 | } | 1420 | } |
1413 | switch (gss_cred->gc_service) { | 1421 | switch (gss_cred->gc_service) { |
1414 | case RPC_GSS_SVC_NONE: | 1422 | case RPC_GSS_SVC_NONE: |
1415 | status = encode(rqstp, p, obj); | 1423 | gss_wrap_req_encode(encode, rqstp, p, obj); |
1424 | status = 0; | ||
1416 | break; | 1425 | break; |
1417 | case RPC_GSS_SVC_INTEGRITY: | 1426 | case RPC_GSS_SVC_INTEGRITY: |
1418 | status = gss_wrap_req_integ(cred, ctx, encode, | 1427 | status = gss_wrap_req_integ(cred, ctx, encode, |
@@ -1494,10 +1503,19 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1494 | return 0; | 1503 | return 0; |
1495 | } | 1504 | } |
1496 | 1505 | ||
1506 | static int | ||
1507 | gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, | ||
1508 | __be32 *p, void *obj) | ||
1509 | { | ||
1510 | struct xdr_stream xdr; | ||
1511 | |||
1512 | xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); | ||
1513 | return decode(rqstp, &xdr, obj); | ||
1514 | } | ||
1497 | 1515 | ||
1498 | static int | 1516 | static int |
1499 | gss_unwrap_resp(struct rpc_task *task, | 1517 | gss_unwrap_resp(struct rpc_task *task, |
1500 | kxdrproc_t decode, void *rqstp, __be32 *p, void *obj) | 1518 | kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj) |
1501 | { | 1519 | { |
1502 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; | 1520 | struct rpc_cred *cred = task->tk_rqstp->rq_cred; |
1503 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, | 1521 | struct gss_cred *gss_cred = container_of(cred, struct gss_cred, |
@@ -1528,7 +1546,7 @@ gss_unwrap_resp(struct rpc_task *task, | |||
1528 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) | 1546 | cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) |
1529 | + (savedlen - head->iov_len); | 1547 | + (savedlen - head->iov_len); |
1530 | out_decode: | 1548 | out_decode: |
1531 | status = decode(rqstp, p, obj); | 1549 | status = gss_unwrap_req_decode(decode, rqstp, p, obj); |
1532 | out: | 1550 | out: |
1533 | gss_put_ctx(ctx); | 1551 | gss_put_ctx(ctx); |
1534 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, | 1552 | dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, |
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 75ee993ea057..9576f35ab701 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
@@ -137,7 +137,7 @@ arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4]) | |||
137 | ms_usage = 13; | 137 | ms_usage = 13; |
138 | break; | 138 | break; |
139 | default: | 139 | default: |
140 | return EINVAL;; | 140 | return -EINVAL; |
141 | } | 141 | } |
142 | salt[0] = (ms_usage >> 0) & 0xff; | 142 | salt[0] = (ms_usage >> 0) & 0xff; |
143 | salt[1] = (ms_usage >> 8) & 0xff; | 143 | salt[1] = (ms_usage >> 8) & 0xff; |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index dec2a6fc7c12..bcdae78fdfc6 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -67,7 +67,6 @@ static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b) | |||
67 | 67 | ||
68 | #define RSI_HASHBITS 6 | 68 | #define RSI_HASHBITS 6 |
69 | #define RSI_HASHMAX (1<<RSI_HASHBITS) | 69 | #define RSI_HASHMAX (1<<RSI_HASHBITS) |
70 | #define RSI_HASHMASK (RSI_HASHMAX-1) | ||
71 | 70 | ||
72 | struct rsi { | 71 | struct rsi { |
73 | struct cache_head h; | 72 | struct cache_head h; |
@@ -319,7 +318,6 @@ static struct rsi *rsi_update(struct rsi *new, struct rsi *old) | |||
319 | 318 | ||
320 | #define RSC_HASHBITS 10 | 319 | #define RSC_HASHBITS 10 |
321 | #define RSC_HASHMAX (1<<RSC_HASHBITS) | 320 | #define RSC_HASHMAX (1<<RSC_HASHBITS) |
322 | #define RSC_HASHMASK (RSC_HASHMAX-1) | ||
323 | 321 | ||
324 | #define GSS_SEQ_WIN 128 | 322 | #define GSS_SEQ_WIN 128 |
325 | 323 | ||
diff --git a/net/sunrpc/bc_svc.c b/net/sunrpc/bc_svc.c index 7dcfe0cc3500..1dd1a6890007 100644 --- a/net/sunrpc/bc_svc.c +++ b/net/sunrpc/bc_svc.c | |||
@@ -59,8 +59,8 @@ int bc_send(struct rpc_rqst *req) | |||
59 | ret = task->tk_status; | 59 | ret = task->tk_status; |
60 | rpc_put_task(task); | 60 | rpc_put_task(task); |
61 | } | 61 | } |
62 | return ret; | ||
63 | dprintk("RPC: bc_send ret= %d\n", ret); | 62 | dprintk("RPC: bc_send ret= %d\n", ret); |
63 | return ret; | ||
64 | } | 64 | } |
65 | 65 | ||
66 | #endif /* CONFIG_NFS_V4_1 */ | 66 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index e433e7580e27..72ad836e4fe0 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #define RPCDBG_FACILITY RPCDBG_CACHE | 38 | #define RPCDBG_FACILITY RPCDBG_CACHE |
39 | 39 | ||
40 | static void cache_defer_req(struct cache_req *req, struct cache_head *item); | 40 | static bool cache_defer_req(struct cache_req *req, struct cache_head *item); |
41 | static void cache_revisit_request(struct cache_head *item); | 41 | static void cache_revisit_request(struct cache_head *item); |
42 | 42 | ||
43 | static void cache_init(struct cache_head *h) | 43 | static void cache_init(struct cache_head *h) |
@@ -128,6 +128,7 @@ static void cache_fresh_locked(struct cache_head *head, time_t expiry) | |||
128 | { | 128 | { |
129 | head->expiry_time = expiry; | 129 | head->expiry_time = expiry; |
130 | head->last_refresh = seconds_since_boot(); | 130 | head->last_refresh = seconds_since_boot(); |
131 | smp_wmb(); /* paired with smp_rmb() in cache_is_valid() */ | ||
131 | set_bit(CACHE_VALID, &head->flags); | 132 | set_bit(CACHE_VALID, &head->flags); |
132 | } | 133 | } |
133 | 134 | ||
@@ -208,11 +209,36 @@ static inline int cache_is_valid(struct cache_detail *detail, struct cache_head | |||
208 | /* entry is valid */ | 209 | /* entry is valid */ |
209 | if (test_bit(CACHE_NEGATIVE, &h->flags)) | 210 | if (test_bit(CACHE_NEGATIVE, &h->flags)) |
210 | return -ENOENT; | 211 | return -ENOENT; |
211 | else | 212 | else { |
213 | /* | ||
214 | * In combination with write barrier in | ||
215 | * sunrpc_cache_update, ensures that anyone | ||
216 | * using the cache entry after this sees the | ||
217 | * updated contents: | ||
218 | */ | ||
219 | smp_rmb(); | ||
212 | return 0; | 220 | return 0; |
221 | } | ||
213 | } | 222 | } |
214 | } | 223 | } |
215 | 224 | ||
225 | static int try_to_negate_entry(struct cache_detail *detail, struct cache_head *h) | ||
226 | { | ||
227 | int rv; | ||
228 | |||
229 | write_lock(&detail->hash_lock); | ||
230 | rv = cache_is_valid(detail, h); | ||
231 | if (rv != -EAGAIN) { | ||
232 | write_unlock(&detail->hash_lock); | ||
233 | return rv; | ||
234 | } | ||
235 | set_bit(CACHE_NEGATIVE, &h->flags); | ||
236 | cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); | ||
237 | write_unlock(&detail->hash_lock); | ||
238 | cache_fresh_unlocked(h, detail); | ||
239 | return -ENOENT; | ||
240 | } | ||
241 | |||
216 | /* | 242 | /* |
217 | * This is the generic cache management routine for all | 243 | * This is the generic cache management routine for all |
218 | * the authentication caches. | 244 | * the authentication caches. |
@@ -251,14 +277,8 @@ int cache_check(struct cache_detail *detail, | |||
251 | case -EINVAL: | 277 | case -EINVAL: |
252 | clear_bit(CACHE_PENDING, &h->flags); | 278 | clear_bit(CACHE_PENDING, &h->flags); |
253 | cache_revisit_request(h); | 279 | cache_revisit_request(h); |
254 | if (rv == -EAGAIN) { | 280 | rv = try_to_negate_entry(detail, h); |
255 | set_bit(CACHE_NEGATIVE, &h->flags); | ||
256 | cache_fresh_locked(h, seconds_since_boot()+CACHE_NEW_EXPIRY); | ||
257 | cache_fresh_unlocked(h, detail); | ||
258 | rv = -ENOENT; | ||
259 | } | ||
260 | break; | 281 | break; |
261 | |||
262 | case -EAGAIN: | 282 | case -EAGAIN: |
263 | clear_bit(CACHE_PENDING, &h->flags); | 283 | clear_bit(CACHE_PENDING, &h->flags); |
264 | cache_revisit_request(h); | 284 | cache_revisit_request(h); |
@@ -268,9 +288,11 @@ int cache_check(struct cache_detail *detail, | |||
268 | } | 288 | } |
269 | 289 | ||
270 | if (rv == -EAGAIN) { | 290 | if (rv == -EAGAIN) { |
271 | cache_defer_req(rqstp, h); | 291 | if (!cache_defer_req(rqstp, h)) { |
272 | if (!test_bit(CACHE_PENDING, &h->flags)) { | 292 | /* |
273 | /* Request is not deferred */ | 293 | * Request was not deferred; handle it as best |
294 | * we can ourselves: | ||
295 | */ | ||
274 | rv = cache_is_valid(detail, h); | 296 | rv = cache_is_valid(detail, h); |
275 | if (rv == -EAGAIN) | 297 | if (rv == -EAGAIN) |
276 | rv = -ETIMEDOUT; | 298 | rv = -ETIMEDOUT; |
@@ -618,18 +640,19 @@ static void cache_limit_defers(void) | |||
618 | discard->revisit(discard, 1); | 640 | discard->revisit(discard, 1); |
619 | } | 641 | } |
620 | 642 | ||
621 | static void cache_defer_req(struct cache_req *req, struct cache_head *item) | 643 | /* Return true if and only if a deferred request is queued. */ |
644 | static bool cache_defer_req(struct cache_req *req, struct cache_head *item) | ||
622 | { | 645 | { |
623 | struct cache_deferred_req *dreq; | 646 | struct cache_deferred_req *dreq; |
624 | 647 | ||
625 | if (req->thread_wait) { | 648 | if (req->thread_wait) { |
626 | cache_wait_req(req, item); | 649 | cache_wait_req(req, item); |
627 | if (!test_bit(CACHE_PENDING, &item->flags)) | 650 | if (!test_bit(CACHE_PENDING, &item->flags)) |
628 | return; | 651 | return false; |
629 | } | 652 | } |
630 | dreq = req->defer(req); | 653 | dreq = req->defer(req); |
631 | if (dreq == NULL) | 654 | if (dreq == NULL) |
632 | return; | 655 | return false; |
633 | setup_deferral(dreq, item, 1); | 656 | setup_deferral(dreq, item, 1); |
634 | if (!test_bit(CACHE_PENDING, &item->flags)) | 657 | if (!test_bit(CACHE_PENDING, &item->flags)) |
635 | /* Bit could have been cleared before we managed to | 658 | /* Bit could have been cleared before we managed to |
@@ -638,6 +661,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item) | |||
638 | cache_revisit_request(item); | 661 | cache_revisit_request(item); |
639 | 662 | ||
640 | cache_limit_defers(); | 663 | cache_limit_defers(); |
664 | return true; | ||
641 | } | 665 | } |
642 | 666 | ||
643 | static void cache_revisit_request(struct cache_head *item) | 667 | static void cache_revisit_request(struct cache_head *item) |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 92ce94f5146b..57d344cf2256 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -1095,7 +1095,7 @@ static void | |||
1095 | rpc_xdr_encode(struct rpc_task *task) | 1095 | rpc_xdr_encode(struct rpc_task *task) |
1096 | { | 1096 | { |
1097 | struct rpc_rqst *req = task->tk_rqstp; | 1097 | struct rpc_rqst *req = task->tk_rqstp; |
1098 | kxdrproc_t encode; | 1098 | kxdreproc_t encode; |
1099 | __be32 *p; | 1099 | __be32 *p; |
1100 | 1100 | ||
1101 | dprint_status(task); | 1101 | dprint_status(task); |
@@ -1535,7 +1535,7 @@ call_decode(struct rpc_task *task) | |||
1535 | { | 1535 | { |
1536 | struct rpc_clnt *clnt = task->tk_client; | 1536 | struct rpc_clnt *clnt = task->tk_client; |
1537 | struct rpc_rqst *req = task->tk_rqstp; | 1537 | struct rpc_rqst *req = task->tk_rqstp; |
1538 | kxdrproc_t decode = task->tk_msg.rpc_proc->p_decode; | 1538 | kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; |
1539 | __be32 *p; | 1539 | __be32 *p; |
1540 | 1540 | ||
1541 | dprintk("RPC: %5u call_decode (status %d)\n", | 1541 | dprintk("RPC: %5u call_decode (status %d)\n", |
@@ -1776,12 +1776,11 @@ out_overflow: | |||
1776 | goto out_garbage; | 1776 | goto out_garbage; |
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj) | 1779 | static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
1780 | { | 1780 | { |
1781 | return 0; | ||
1782 | } | 1781 | } |
1783 | 1782 | ||
1784 | static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj) | 1783 | static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) |
1785 | { | 1784 | { |
1786 | return 0; | 1785 | return 0; |
1787 | } | 1786 | } |
@@ -1830,23 +1829,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt, | |||
1830 | const struct rpc_task *task) | 1829 | const struct rpc_task *task) |
1831 | { | 1830 | { |
1832 | const char *rpc_waitq = "none"; | 1831 | const char *rpc_waitq = "none"; |
1833 | char *p, action[KSYM_SYMBOL_LEN]; | ||
1834 | 1832 | ||
1835 | if (RPC_IS_QUEUED(task)) | 1833 | if (RPC_IS_QUEUED(task)) |
1836 | rpc_waitq = rpc_qname(task->tk_waitqueue); | 1834 | rpc_waitq = rpc_qname(task->tk_waitqueue); |
1837 | 1835 | ||
1838 | /* map tk_action pointer to a function name; then trim off | 1836 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n", |
1839 | * the "+0x0 [sunrpc]" */ | ||
1840 | sprint_symbol(action, (unsigned long)task->tk_action); | ||
1841 | p = strchr(action, '+'); | ||
1842 | if (p) | ||
1843 | *p = '\0'; | ||
1844 | |||
1845 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", | ||
1846 | task->tk_pid, task->tk_flags, task->tk_status, | 1837 | task->tk_pid, task->tk_flags, task->tk_status, |
1847 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, | 1838 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, |
1848 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), | 1839 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), |
1849 | action, rpc_waitq); | 1840 | task->tk_action, rpc_waitq); |
1850 | } | 1841 | } |
1851 | 1842 | ||
1852 | void rpc_show_tasks(void) | 1843 | void rpc_show_tasks(void) |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 09f01f41e55a..72bc53683965 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -474,7 +474,7 @@ static int __rpc_create_common(struct inode *dir, struct dentry *dentry, | |||
474 | { | 474 | { |
475 | struct inode *inode; | 475 | struct inode *inode; |
476 | 476 | ||
477 | BUG_ON(!d_unhashed(dentry)); | 477 | d_drop(dentry); |
478 | inode = rpc_get_inode(dir->i_sb, mode); | 478 | inode = rpc_get_inode(dir->i_sb, mode); |
479 | if (!inode) | 479 | if (!inode) |
480 | goto out_err; | 480 | goto out_err; |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index fa6d7ca2c851..c652e4cc9fe9 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -57,10 +57,6 @@ enum { | |||
57 | RPCBPROC_GETSTAT, | 57 | RPCBPROC_GETSTAT, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define RPCB_HIGHPROC_2 RPCBPROC_CALLIT | ||
61 | #define RPCB_HIGHPROC_3 RPCBPROC_TADDR2UADDR | ||
62 | #define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT | ||
63 | |||
64 | /* | 60 | /* |
65 | * r_owner | 61 | * r_owner |
66 | * | 62 | * |
@@ -693,46 +689,37 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) | |||
693 | * XDR functions for rpcbind | 689 | * XDR functions for rpcbind |
694 | */ | 690 | */ |
695 | 691 | ||
696 | static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p, | 692 | static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, |
697 | const struct rpcbind_args *rpcb) | 693 | const struct rpcbind_args *rpcb) |
698 | { | 694 | { |
699 | struct rpc_task *task = req->rq_task; | 695 | struct rpc_task *task = req->rq_task; |
700 | struct xdr_stream xdr; | 696 | __be32 *p; |
701 | 697 | ||
702 | dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", | 698 | dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", |
703 | task->tk_pid, task->tk_msg.rpc_proc->p_name, | 699 | task->tk_pid, task->tk_msg.rpc_proc->p_name, |
704 | rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); | 700 | rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); |
705 | 701 | ||
706 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 702 | p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2); |
707 | 703 | *p++ = cpu_to_be32(rpcb->r_prog); | |
708 | p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz); | 704 | *p++ = cpu_to_be32(rpcb->r_vers); |
709 | if (unlikely(p == NULL)) | 705 | *p++ = cpu_to_be32(rpcb->r_prot); |
710 | return -EIO; | 706 | *p = cpu_to_be32(rpcb->r_port); |
711 | |||
712 | *p++ = htonl(rpcb->r_prog); | ||
713 | *p++ = htonl(rpcb->r_vers); | ||
714 | *p++ = htonl(rpcb->r_prot); | ||
715 | *p = htonl(rpcb->r_port); | ||
716 | |||
717 | return 0; | ||
718 | } | 707 | } |
719 | 708 | ||
720 | static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, | 709 | static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr, |
721 | struct rpcbind_args *rpcb) | 710 | struct rpcbind_args *rpcb) |
722 | { | 711 | { |
723 | struct rpc_task *task = req->rq_task; | 712 | struct rpc_task *task = req->rq_task; |
724 | struct xdr_stream xdr; | ||
725 | unsigned long port; | 713 | unsigned long port; |
726 | 714 | __be32 *p; | |
727 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | ||
728 | 715 | ||
729 | rpcb->r_port = 0; | 716 | rpcb->r_port = 0; |
730 | 717 | ||
731 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | 718 | p = xdr_inline_decode(xdr, 4); |
732 | if (unlikely(p == NULL)) | 719 | if (unlikely(p == NULL)) |
733 | return -EIO; | 720 | return -EIO; |
734 | 721 | ||
735 | port = ntohl(*p); | 722 | port = be32_to_cpup(p); |
736 | dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, | 723 | dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, |
737 | task->tk_msg.rpc_proc->p_name, port); | 724 | task->tk_msg.rpc_proc->p_name, port); |
738 | if (unlikely(port > USHRT_MAX)) | 725 | if (unlikely(port > USHRT_MAX)) |
@@ -742,20 +729,18 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, | |||
742 | return 0; | 729 | return 0; |
743 | } | 730 | } |
744 | 731 | ||
745 | static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, | 732 | static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr, |
746 | unsigned int *boolp) | 733 | unsigned int *boolp) |
747 | { | 734 | { |
748 | struct rpc_task *task = req->rq_task; | 735 | struct rpc_task *task = req->rq_task; |
749 | struct xdr_stream xdr; | 736 | __be32 *p; |
750 | |||
751 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | ||
752 | 737 | ||
753 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | 738 | p = xdr_inline_decode(xdr, 4); |
754 | if (unlikely(p == NULL)) | 739 | if (unlikely(p == NULL)) |
755 | return -EIO; | 740 | return -EIO; |
756 | 741 | ||
757 | *boolp = 0; | 742 | *boolp = 0; |
758 | if (*p) | 743 | if (*p != xdr_zero) |
759 | *boolp = 1; | 744 | *boolp = 1; |
760 | 745 | ||
761 | dprintk("RPC: %5u RPCB_%s call %s\n", | 746 | dprintk("RPC: %5u RPCB_%s call %s\n", |
@@ -764,73 +749,53 @@ static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, | |||
764 | return 0; | 749 | return 0; |
765 | } | 750 | } |
766 | 751 | ||
767 | static int encode_rpcb_string(struct xdr_stream *xdr, const char *string, | 752 | static void encode_rpcb_string(struct xdr_stream *xdr, const char *string, |
768 | const u32 maxstrlen) | 753 | const u32 maxstrlen) |
769 | { | 754 | { |
770 | u32 len; | ||
771 | __be32 *p; | 755 | __be32 *p; |
756 | u32 len; | ||
772 | 757 | ||
773 | if (unlikely(string == NULL)) | ||
774 | return -EIO; | ||
775 | len = strlen(string); | 758 | len = strlen(string); |
776 | if (unlikely(len > maxstrlen)) | 759 | BUG_ON(len > maxstrlen); |
777 | return -EIO; | 760 | p = xdr_reserve_space(xdr, 4 + len); |
778 | |||
779 | p = xdr_reserve_space(xdr, sizeof(__be32) + len); | ||
780 | if (unlikely(p == NULL)) | ||
781 | return -EIO; | ||
782 | xdr_encode_opaque(p, string, len); | 761 | xdr_encode_opaque(p, string, len); |
783 | |||
784 | return 0; | ||
785 | } | 762 | } |
786 | 763 | ||
787 | static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p, | 764 | static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, |
788 | const struct rpcbind_args *rpcb) | 765 | const struct rpcbind_args *rpcb) |
789 | { | 766 | { |
790 | struct rpc_task *task = req->rq_task; | 767 | struct rpc_task *task = req->rq_task; |
791 | struct xdr_stream xdr; | 768 | __be32 *p; |
792 | 769 | ||
793 | dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", | 770 | dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", |
794 | task->tk_pid, task->tk_msg.rpc_proc->p_name, | 771 | task->tk_pid, task->tk_msg.rpc_proc->p_name, |
795 | rpcb->r_prog, rpcb->r_vers, | 772 | rpcb->r_prog, rpcb->r_vers, |
796 | rpcb->r_netid, rpcb->r_addr); | 773 | rpcb->r_netid, rpcb->r_addr); |
797 | 774 | ||
798 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 775 | p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2); |
799 | 776 | *p++ = cpu_to_be32(rpcb->r_prog); | |
800 | p = xdr_reserve_space(&xdr, | 777 | *p = cpu_to_be32(rpcb->r_vers); |
801 | sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz)); | ||
802 | if (unlikely(p == NULL)) | ||
803 | return -EIO; | ||
804 | *p++ = htonl(rpcb->r_prog); | ||
805 | *p = htonl(rpcb->r_vers); | ||
806 | |||
807 | if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN)) | ||
808 | return -EIO; | ||
809 | if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN)) | ||
810 | return -EIO; | ||
811 | if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN)) | ||
812 | return -EIO; | ||
813 | 778 | ||
814 | return 0; | 779 | encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN); |
780 | encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN); | ||
781 | encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); | ||
815 | } | 782 | } |
816 | 783 | ||
817 | static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, | 784 | static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, |
818 | struct rpcbind_args *rpcb) | 785 | struct rpcbind_args *rpcb) |
819 | { | 786 | { |
820 | struct sockaddr_storage address; | 787 | struct sockaddr_storage address; |
821 | struct sockaddr *sap = (struct sockaddr *)&address; | 788 | struct sockaddr *sap = (struct sockaddr *)&address; |
822 | struct rpc_task *task = req->rq_task; | 789 | struct rpc_task *task = req->rq_task; |
823 | struct xdr_stream xdr; | 790 | __be32 *p; |
824 | u32 len; | 791 | u32 len; |
825 | 792 | ||
826 | rpcb->r_port = 0; | 793 | rpcb->r_port = 0; |
827 | 794 | ||
828 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | 795 | p = xdr_inline_decode(xdr, 4); |
829 | |||
830 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | ||
831 | if (unlikely(p == NULL)) | 796 | if (unlikely(p == NULL)) |
832 | goto out_fail; | 797 | goto out_fail; |
833 | len = ntohl(*p); | 798 | len = be32_to_cpup(p); |
834 | 799 | ||
835 | /* | 800 | /* |
836 | * If the returned universal address is a null string, | 801 | * If the returned universal address is a null string, |
@@ -845,7 +810,7 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, | |||
845 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) | 810 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) |
846 | goto out_fail; | 811 | goto out_fail; |
847 | 812 | ||
848 | p = xdr_inline_decode(&xdr, len); | 813 | p = xdr_inline_decode(xdr, len); |
849 | if (unlikely(p == NULL)) | 814 | if (unlikely(p == NULL)) |
850 | goto out_fail; | 815 | goto out_fail; |
851 | dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, | 816 | dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, |
@@ -871,8 +836,8 @@ out_fail: | |||
871 | static struct rpc_procinfo rpcb_procedures2[] = { | 836 | static struct rpc_procinfo rpcb_procedures2[] = { |
872 | [RPCBPROC_SET] = { | 837 | [RPCBPROC_SET] = { |
873 | .p_proc = RPCBPROC_SET, | 838 | .p_proc = RPCBPROC_SET, |
874 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 839 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
875 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 840 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
876 | .p_arglen = RPCB_mappingargs_sz, | 841 | .p_arglen = RPCB_mappingargs_sz, |
877 | .p_replen = RPCB_setres_sz, | 842 | .p_replen = RPCB_setres_sz, |
878 | .p_statidx = RPCBPROC_SET, | 843 | .p_statidx = RPCBPROC_SET, |
@@ -881,8 +846,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
881 | }, | 846 | }, |
882 | [RPCBPROC_UNSET] = { | 847 | [RPCBPROC_UNSET] = { |
883 | .p_proc = RPCBPROC_UNSET, | 848 | .p_proc = RPCBPROC_UNSET, |
884 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 849 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
885 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 850 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
886 | .p_arglen = RPCB_mappingargs_sz, | 851 | .p_arglen = RPCB_mappingargs_sz, |
887 | .p_replen = RPCB_setres_sz, | 852 | .p_replen = RPCB_setres_sz, |
888 | .p_statidx = RPCBPROC_UNSET, | 853 | .p_statidx = RPCBPROC_UNSET, |
@@ -891,8 +856,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
891 | }, | 856 | }, |
892 | [RPCBPROC_GETPORT] = { | 857 | [RPCBPROC_GETPORT] = { |
893 | .p_proc = RPCBPROC_GETPORT, | 858 | .p_proc = RPCBPROC_GETPORT, |
894 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 859 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
895 | .p_decode = (kxdrproc_t)rpcb_dec_getport, | 860 | .p_decode = (kxdrdproc_t)rpcb_dec_getport, |
896 | .p_arglen = RPCB_mappingargs_sz, | 861 | .p_arglen = RPCB_mappingargs_sz, |
897 | .p_replen = RPCB_getportres_sz, | 862 | .p_replen = RPCB_getportres_sz, |
898 | .p_statidx = RPCBPROC_GETPORT, | 863 | .p_statidx = RPCBPROC_GETPORT, |
@@ -904,8 +869,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
904 | static struct rpc_procinfo rpcb_procedures3[] = { | 869 | static struct rpc_procinfo rpcb_procedures3[] = { |
905 | [RPCBPROC_SET] = { | 870 | [RPCBPROC_SET] = { |
906 | .p_proc = RPCBPROC_SET, | 871 | .p_proc = RPCBPROC_SET, |
907 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 872 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
908 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 873 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
909 | .p_arglen = RPCB_getaddrargs_sz, | 874 | .p_arglen = RPCB_getaddrargs_sz, |
910 | .p_replen = RPCB_setres_sz, | 875 | .p_replen = RPCB_setres_sz, |
911 | .p_statidx = RPCBPROC_SET, | 876 | .p_statidx = RPCBPROC_SET, |
@@ -914,8 +879,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
914 | }, | 879 | }, |
915 | [RPCBPROC_UNSET] = { | 880 | [RPCBPROC_UNSET] = { |
916 | .p_proc = RPCBPROC_UNSET, | 881 | .p_proc = RPCBPROC_UNSET, |
917 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 882 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
918 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 883 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
919 | .p_arglen = RPCB_getaddrargs_sz, | 884 | .p_arglen = RPCB_getaddrargs_sz, |
920 | .p_replen = RPCB_setres_sz, | 885 | .p_replen = RPCB_setres_sz, |
921 | .p_statidx = RPCBPROC_UNSET, | 886 | .p_statidx = RPCBPROC_UNSET, |
@@ -924,8 +889,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
924 | }, | 889 | }, |
925 | [RPCBPROC_GETADDR] = { | 890 | [RPCBPROC_GETADDR] = { |
926 | .p_proc = RPCBPROC_GETADDR, | 891 | .p_proc = RPCBPROC_GETADDR, |
927 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 892 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
928 | .p_decode = (kxdrproc_t)rpcb_dec_getaddr, | 893 | .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, |
929 | .p_arglen = RPCB_getaddrargs_sz, | 894 | .p_arglen = RPCB_getaddrargs_sz, |
930 | .p_replen = RPCB_getaddrres_sz, | 895 | .p_replen = RPCB_getaddrres_sz, |
931 | .p_statidx = RPCBPROC_GETADDR, | 896 | .p_statidx = RPCBPROC_GETADDR, |
@@ -937,8 +902,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
937 | static struct rpc_procinfo rpcb_procedures4[] = { | 902 | static struct rpc_procinfo rpcb_procedures4[] = { |
938 | [RPCBPROC_SET] = { | 903 | [RPCBPROC_SET] = { |
939 | .p_proc = RPCBPROC_SET, | 904 | .p_proc = RPCBPROC_SET, |
940 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 905 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
941 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 906 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
942 | .p_arglen = RPCB_getaddrargs_sz, | 907 | .p_arglen = RPCB_getaddrargs_sz, |
943 | .p_replen = RPCB_setres_sz, | 908 | .p_replen = RPCB_setres_sz, |
944 | .p_statidx = RPCBPROC_SET, | 909 | .p_statidx = RPCBPROC_SET, |
@@ -947,8 +912,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { | |||
947 | }, | 912 | }, |
948 | [RPCBPROC_UNSET] = { | 913 | [RPCBPROC_UNSET] = { |
949 | .p_proc = RPCBPROC_UNSET, | 914 | .p_proc = RPCBPROC_UNSET, |
950 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 915 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
951 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 916 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
952 | .p_arglen = RPCB_getaddrargs_sz, | 917 | .p_arglen = RPCB_getaddrargs_sz, |
953 | .p_replen = RPCB_setres_sz, | 918 | .p_replen = RPCB_setres_sz, |
954 | .p_statidx = RPCBPROC_UNSET, | 919 | .p_statidx = RPCBPROC_UNSET, |
@@ -957,8 +922,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { | |||
957 | }, | 922 | }, |
958 | [RPCBPROC_GETADDR] = { | 923 | [RPCBPROC_GETADDR] = { |
959 | .p_proc = RPCBPROC_GETADDR, | 924 | .p_proc = RPCBPROC_GETADDR, |
960 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 925 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
961 | .p_decode = (kxdrproc_t)rpcb_dec_getaddr, | 926 | .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, |
962 | .p_arglen = RPCB_getaddrargs_sz, | 927 | .p_arglen = RPCB_getaddrargs_sz, |
963 | .p_replen = RPCB_getaddrres_sz, | 928 | .p_replen = RPCB_getaddrres_sz, |
964 | .p_statidx = RPCBPROC_GETADDR, | 929 | .p_statidx = RPCBPROC_GETADDR, |
@@ -993,19 +958,19 @@ static struct rpcb_info rpcb_next_version6[] = { | |||
993 | 958 | ||
994 | static struct rpc_version rpcb_version2 = { | 959 | static struct rpc_version rpcb_version2 = { |
995 | .number = RPCBVERS_2, | 960 | .number = RPCBVERS_2, |
996 | .nrprocs = RPCB_HIGHPROC_2, | 961 | .nrprocs = ARRAY_SIZE(rpcb_procedures2), |
997 | .procs = rpcb_procedures2 | 962 | .procs = rpcb_procedures2 |
998 | }; | 963 | }; |
999 | 964 | ||
1000 | static struct rpc_version rpcb_version3 = { | 965 | static struct rpc_version rpcb_version3 = { |
1001 | .number = RPCBVERS_3, | 966 | .number = RPCBVERS_3, |
1002 | .nrprocs = RPCB_HIGHPROC_3, | 967 | .nrprocs = ARRAY_SIZE(rpcb_procedures3), |
1003 | .procs = rpcb_procedures3 | 968 | .procs = rpcb_procedures3 |
1004 | }; | 969 | }; |
1005 | 970 | ||
1006 | static struct rpc_version rpcb_version4 = { | 971 | static struct rpc_version rpcb_version4 = { |
1007 | .number = RPCBVERS_4, | 972 | .number = RPCBVERS_4, |
1008 | .nrprocs = RPCB_HIGHPROC_4, | 973 | .nrprocs = ARRAY_SIZE(rpcb_procedures4), |
1009 | .procs = rpcb_procedures4 | 974 | .procs = rpcb_procedures4 |
1010 | }; | 975 | }; |
1011 | 976 | ||
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 6359c42c4941..08e05a8ce025 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -488,10 +488,6 @@ svc_destroy(struct svc_serv *serv) | |||
488 | if (svc_serv_is_pooled(serv)) | 488 | if (svc_serv_is_pooled(serv)) |
489 | svc_pool_map_put(); | 489 | svc_pool_map_put(); |
490 | 490 | ||
491 | #if defined(CONFIG_NFS_V4_1) | ||
492 | svc_sock_destroy(serv->bc_xprt); | ||
493 | #endif /* CONFIG_NFS_V4_1 */ | ||
494 | |||
495 | svc_unregister(serv); | 491 | svc_unregister(serv); |
496 | kfree(serv->sv_pools); | 492 | kfree(serv->sv_pools); |
497 | kfree(serv); | 493 | kfree(serv); |
@@ -1005,6 +1001,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
1005 | rqstp->rq_splice_ok = 1; | 1001 | rqstp->rq_splice_ok = 1; |
1006 | /* Will be turned off only when NFSv4 Sessions are used */ | 1002 | /* Will be turned off only when NFSv4 Sessions are used */ |
1007 | rqstp->rq_usedeferral = 1; | 1003 | rqstp->rq_usedeferral = 1; |
1004 | rqstp->rq_dropme = false; | ||
1008 | 1005 | ||
1009 | /* Setup reply header */ | 1006 | /* Setup reply header */ |
1010 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); | 1007 | rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); |
@@ -1106,7 +1103,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
1106 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); | 1103 | *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); |
1107 | 1104 | ||
1108 | /* Encode reply */ | 1105 | /* Encode reply */ |
1109 | if (*statp == rpc_drop_reply) { | 1106 | if (rqstp->rq_dropme) { |
1110 | if (procp->pc_release) | 1107 | if (procp->pc_release) |
1111 | procp->pc_release(rqstp, NULL, rqstp->rq_resp); | 1108 | procp->pc_release(rqstp, NULL, rqstp->rq_resp); |
1112 | goto dropit; | 1109 | goto dropit; |
@@ -1147,7 +1144,6 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) | |||
1147 | dropit: | 1144 | dropit: |
1148 | svc_authorise(rqstp); /* doesn't hurt to call this twice */ | 1145 | svc_authorise(rqstp); /* doesn't hurt to call this twice */ |
1149 | dprintk("svc: svc_process dropit\n"); | 1146 | dprintk("svc: svc_process dropit\n"); |
1150 | svc_drop(rqstp); | ||
1151 | return 0; | 1147 | return 0; |
1152 | 1148 | ||
1153 | err_short_len: | 1149 | err_short_len: |
@@ -1218,7 +1214,6 @@ svc_process(struct svc_rqst *rqstp) | |||
1218 | struct kvec *resv = &rqstp->rq_res.head[0]; | 1214 | struct kvec *resv = &rqstp->rq_res.head[0]; |
1219 | struct svc_serv *serv = rqstp->rq_server; | 1215 | struct svc_serv *serv = rqstp->rq_server; |
1220 | u32 dir; | 1216 | u32 dir; |
1221 | int error; | ||
1222 | 1217 | ||
1223 | /* | 1218 | /* |
1224 | * Setup response xdr_buf. | 1219 | * Setup response xdr_buf. |
@@ -1246,11 +1241,13 @@ svc_process(struct svc_rqst *rqstp) | |||
1246 | return 0; | 1241 | return 0; |
1247 | } | 1242 | } |
1248 | 1243 | ||
1249 | error = svc_process_common(rqstp, argv, resv); | 1244 | /* Returns 1 for send, 0 for drop */ |
1250 | if (error <= 0) | 1245 | if (svc_process_common(rqstp, argv, resv)) |
1251 | return error; | 1246 | return svc_send(rqstp); |
1252 | 1247 | else { | |
1253 | return svc_send(rqstp); | 1248 | svc_drop(rqstp); |
1249 | return 0; | ||
1250 | } | ||
1254 | } | 1251 | } |
1255 | 1252 | ||
1256 | #if defined(CONFIG_NFS_V4_1) | 1253 | #if defined(CONFIG_NFS_V4_1) |
@@ -1264,10 +1261,9 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
1264 | { | 1261 | { |
1265 | struct kvec *argv = &rqstp->rq_arg.head[0]; | 1262 | struct kvec *argv = &rqstp->rq_arg.head[0]; |
1266 | struct kvec *resv = &rqstp->rq_res.head[0]; | 1263 | struct kvec *resv = &rqstp->rq_res.head[0]; |
1267 | int error; | ||
1268 | 1264 | ||
1269 | /* Build the svc_rqst used by the common processing routine */ | 1265 | /* Build the svc_rqst used by the common processing routine */ |
1270 | rqstp->rq_xprt = serv->bc_xprt; | 1266 | rqstp->rq_xprt = serv->sv_bc_xprt; |
1271 | rqstp->rq_xid = req->rq_xid; | 1267 | rqstp->rq_xid = req->rq_xid; |
1272 | rqstp->rq_prot = req->rq_xprt->prot; | 1268 | rqstp->rq_prot = req->rq_xprt->prot; |
1273 | rqstp->rq_server = serv; | 1269 | rqstp->rq_server = serv; |
@@ -1292,12 +1288,15 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
1292 | svc_getu32(argv); /* XID */ | 1288 | svc_getu32(argv); /* XID */ |
1293 | svc_getnl(argv); /* CALLDIR */ | 1289 | svc_getnl(argv); /* CALLDIR */ |
1294 | 1290 | ||
1295 | error = svc_process_common(rqstp, argv, resv); | 1291 | /* Returns 1 for send, 0 for drop */ |
1296 | if (error <= 0) | 1292 | if (svc_process_common(rqstp, argv, resv)) { |
1297 | return error; | 1293 | memcpy(&req->rq_snd_buf, &rqstp->rq_res, |
1298 | 1294 | sizeof(req->rq_snd_buf)); | |
1299 | memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf)); | 1295 | return bc_send(req); |
1300 | return bc_send(req); | 1296 | } else { |
1297 | /* Nothing to do to drop request */ | ||
1298 | return 0; | ||
1299 | } | ||
1301 | } | 1300 | } |
1302 | EXPORT_SYMBOL(bc_svc_process); | 1301 | EXPORT_SYMBOL(bc_svc_process); |
1303 | #endif /* CONFIG_NFS_V4_1 */ | 1302 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 3f2c5559ca1a..ab86b7927f84 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/sunrpc/stats.h> | 13 | #include <linux/sunrpc/stats.h> |
14 | #include <linux/sunrpc/svc_xprt.h> | 14 | #include <linux/sunrpc/svc_xprt.h> |
15 | #include <linux/sunrpc/svcsock.h> | 15 | #include <linux/sunrpc/svcsock.h> |
16 | #include <linux/sunrpc/xprt.h> | ||
16 | 17 | ||
17 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 18 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
18 | 19 | ||
@@ -128,6 +129,9 @@ static void svc_xprt_free(struct kref *kref) | |||
128 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) | 129 | if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) |
129 | svcauth_unix_info_release(xprt); | 130 | svcauth_unix_info_release(xprt); |
130 | put_net(xprt->xpt_net); | 131 | put_net(xprt->xpt_net); |
132 | /* See comment on corresponding get in xs_setup_bc_tcp(): */ | ||
133 | if (xprt->xpt_bc_xprt) | ||
134 | xprt_put(xprt->xpt_bc_xprt); | ||
131 | xprt->xpt_ops->xpo_free(xprt); | 135 | xprt->xpt_ops->xpo_free(xprt); |
132 | module_put(owner); | 136 | module_put(owner); |
133 | } | 137 | } |
@@ -303,6 +307,15 @@ static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) | |||
303 | list_del(&rqstp->rq_list); | 307 | list_del(&rqstp->rq_list); |
304 | } | 308 | } |
305 | 309 | ||
310 | static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt) | ||
311 | { | ||
312 | if (xprt->xpt_flags & ((1<<XPT_CONN)|(1<<XPT_CLOSE))) | ||
313 | return true; | ||
314 | if (xprt->xpt_flags & ((1<<XPT_DATA)|(1<<XPT_DEFERRED))) | ||
315 | return xprt->xpt_ops->xpo_has_wspace(xprt); | ||
316 | return false; | ||
317 | } | ||
318 | |||
306 | /* | 319 | /* |
307 | * Queue up a transport with data pending. If there are idle nfsd | 320 | * Queue up a transport with data pending. If there are idle nfsd |
308 | * processes, wake 'em up. | 321 | * processes, wake 'em up. |
@@ -315,8 +328,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
315 | struct svc_rqst *rqstp; | 328 | struct svc_rqst *rqstp; |
316 | int cpu; | 329 | int cpu; |
317 | 330 | ||
318 | if (!(xprt->xpt_flags & | 331 | if (!svc_xprt_has_something_to_do(xprt)) |
319 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) | ||
320 | return; | 332 | return; |
321 | 333 | ||
322 | cpu = get_cpu(); | 334 | cpu = get_cpu(); |
@@ -343,28 +355,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
343 | dprintk("svc: transport %p busy, not enqueued\n", xprt); | 355 | dprintk("svc: transport %p busy, not enqueued\n", xprt); |
344 | goto out_unlock; | 356 | goto out_unlock; |
345 | } | 357 | } |
346 | BUG_ON(xprt->xpt_pool != NULL); | ||
347 | xprt->xpt_pool = pool; | ||
348 | |||
349 | /* Handle pending connection */ | ||
350 | if (test_bit(XPT_CONN, &xprt->xpt_flags)) | ||
351 | goto process; | ||
352 | |||
353 | /* Handle close in-progress */ | ||
354 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) | ||
355 | goto process; | ||
356 | |||
357 | /* Check if we have space to reply to a request */ | ||
358 | if (!xprt->xpt_ops->xpo_has_wspace(xprt)) { | ||
359 | /* Don't enqueue while not enough space for reply */ | ||
360 | dprintk("svc: no write space, transport %p not enqueued\n", | ||
361 | xprt); | ||
362 | xprt->xpt_pool = NULL; | ||
363 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
364 | goto out_unlock; | ||
365 | } | ||
366 | 358 | ||
367 | process: | ||
368 | if (!list_empty(&pool->sp_threads)) { | 359 | if (!list_empty(&pool->sp_threads)) { |
369 | rqstp = list_entry(pool->sp_threads.next, | 360 | rqstp = list_entry(pool->sp_threads.next, |
370 | struct svc_rqst, | 361 | struct svc_rqst, |
@@ -381,13 +372,11 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
381 | rqstp->rq_reserved = serv->sv_max_mesg; | 372 | rqstp->rq_reserved = serv->sv_max_mesg; |
382 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | 373 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); |
383 | pool->sp_stats.threads_woken++; | 374 | pool->sp_stats.threads_woken++; |
384 | BUG_ON(xprt->xpt_pool != pool); | ||
385 | wake_up(&rqstp->rq_wait); | 375 | wake_up(&rqstp->rq_wait); |
386 | } else { | 376 | } else { |
387 | dprintk("svc: transport %p put into queue\n", xprt); | 377 | dprintk("svc: transport %p put into queue\n", xprt); |
388 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); | 378 | list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); |
389 | pool->sp_stats.sockets_queued++; | 379 | pool->sp_stats.sockets_queued++; |
390 | BUG_ON(xprt->xpt_pool != pool); | ||
391 | } | 380 | } |
392 | 381 | ||
393 | out_unlock: | 382 | out_unlock: |
@@ -426,7 +415,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) | |||
426 | void svc_xprt_received(struct svc_xprt *xprt) | 415 | void svc_xprt_received(struct svc_xprt *xprt) |
427 | { | 416 | { |
428 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | 417 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); |
429 | xprt->xpt_pool = NULL; | ||
430 | /* As soon as we clear busy, the xprt could be closed and | 418 | /* As soon as we clear busy, the xprt could be closed and |
431 | * 'put', so we need a reference to call svc_xprt_enqueue with: | 419 | * 'put', so we need a reference to call svc_xprt_enqueue with: |
432 | */ | 420 | */ |
@@ -722,7 +710,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
722 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 710 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
723 | dprintk("svc_recv: found XPT_CLOSE\n"); | 711 | dprintk("svc_recv: found XPT_CLOSE\n"); |
724 | svc_delete_xprt(xprt); | 712 | svc_delete_xprt(xprt); |
725 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | 713 | /* Leave XPT_BUSY set on the dead xprt: */ |
714 | goto out; | ||
715 | } | ||
716 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
726 | struct svc_xprt *newxpt; | 717 | struct svc_xprt *newxpt; |
727 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 718 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
728 | if (newxpt) { | 719 | if (newxpt) { |
@@ -747,28 +738,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
747 | spin_unlock_bh(&serv->sv_lock); | 738 | spin_unlock_bh(&serv->sv_lock); |
748 | svc_xprt_received(newxpt); | 739 | svc_xprt_received(newxpt); |
749 | } | 740 | } |
750 | svc_xprt_received(xprt); | 741 | } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { |
751 | } else { | ||
752 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 742 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
753 | rqstp, pool->sp_id, xprt, | 743 | rqstp, pool->sp_id, xprt, |
754 | atomic_read(&xprt->xpt_ref.refcount)); | 744 | atomic_read(&xprt->xpt_ref.refcount)); |
755 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); | 745 | rqstp->rq_deferred = svc_deferred_dequeue(xprt); |
756 | if (rqstp->rq_deferred) { | 746 | if (rqstp->rq_deferred) |
757 | svc_xprt_received(xprt); | ||
758 | len = svc_deferred_recv(rqstp); | 747 | len = svc_deferred_recv(rqstp); |
759 | } else { | 748 | else |
760 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); | 749 | len = xprt->xpt_ops->xpo_recvfrom(rqstp); |
761 | svc_xprt_received(xprt); | ||
762 | } | ||
763 | dprintk("svc: got len=%d\n", len); | 750 | dprintk("svc: got len=%d\n", len); |
764 | } | 751 | } |
752 | svc_xprt_received(xprt); | ||
765 | 753 | ||
766 | /* No data, incomplete (TCP) read, or accept() */ | 754 | /* No data, incomplete (TCP) read, or accept() */ |
767 | if (len == 0 || len == -EAGAIN) { | 755 | if (len == 0 || len == -EAGAIN) |
768 | rqstp->rq_res.len = 0; | 756 | goto out; |
769 | svc_xprt_release(rqstp); | 757 | |
770 | return -EAGAIN; | ||
771 | } | ||
772 | clear_bit(XPT_OLD, &xprt->xpt_flags); | 758 | clear_bit(XPT_OLD, &xprt->xpt_flags); |
773 | 759 | ||
774 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); | 760 | rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); |
@@ -777,6 +763,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
777 | if (serv->sv_stats) | 763 | if (serv->sv_stats) |
778 | serv->sv_stats->netcnt++; | 764 | serv->sv_stats->netcnt++; |
779 | return len; | 765 | return len; |
766 | out: | ||
767 | rqstp->rq_res.len = 0; | ||
768 | svc_xprt_release(rqstp); | ||
769 | return -EAGAIN; | ||
780 | } | 770 | } |
781 | EXPORT_SYMBOL_GPL(svc_recv); | 771 | EXPORT_SYMBOL_GPL(svc_recv); |
782 | 772 | ||
@@ -935,7 +925,12 @@ void svc_close_xprt(struct svc_xprt *xprt) | |||
935 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) | 925 | if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) |
936 | /* someone else will have to effect the close */ | 926 | /* someone else will have to effect the close */ |
937 | return; | 927 | return; |
938 | 928 | /* | |
929 | * We expect svc_close_xprt() to work even when no threads are | ||
930 | * running (e.g., while configuring the server before starting | ||
931 | * any threads), so if the transport isn't busy, we delete | ||
932 | * it ourself: | ||
933 | */ | ||
939 | svc_delete_xprt(xprt); | 934 | svc_delete_xprt(xprt); |
940 | } | 935 | } |
941 | EXPORT_SYMBOL_GPL(svc_close_xprt); | 936 | EXPORT_SYMBOL_GPL(svc_close_xprt); |
@@ -945,16 +940,16 @@ void svc_close_all(struct list_head *xprt_list) | |||
945 | struct svc_xprt *xprt; | 940 | struct svc_xprt *xprt; |
946 | struct svc_xprt *tmp; | 941 | struct svc_xprt *tmp; |
947 | 942 | ||
943 | /* | ||
944 | * The server is shutting down, and no more threads are running. | ||
945 | * svc_xprt_enqueue() might still be running, but at worst it | ||
946 | * will re-add the xprt to sp_sockets, which will soon get | ||
947 | * freed. So we don't bother with any more locking, and don't | ||
948 | * leave the close to the (nonexistent) server threads: | ||
949 | */ | ||
948 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { | 950 | list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { |
949 | set_bit(XPT_CLOSE, &xprt->xpt_flags); | 951 | set_bit(XPT_CLOSE, &xprt->xpt_flags); |
950 | if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { | 952 | svc_delete_xprt(xprt); |
951 | /* Waiting to be processed, but no threads left, | ||
952 | * So just remove it from the waiting list | ||
953 | */ | ||
954 | list_del_init(&xprt->xpt_ready); | ||
955 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | ||
956 | } | ||
957 | svc_close_xprt(xprt); | ||
958 | } | 953 | } |
959 | } | 954 | } |
960 | 955 | ||
@@ -1028,6 +1023,7 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req) | |||
1028 | } | 1023 | } |
1029 | svc_xprt_get(rqstp->rq_xprt); | 1024 | svc_xprt_get(rqstp->rq_xprt); |
1030 | dr->xprt = rqstp->rq_xprt; | 1025 | dr->xprt = rqstp->rq_xprt; |
1026 | rqstp->rq_dropme = true; | ||
1031 | 1027 | ||
1032 | dr->handle.revisit = svc_revisit; | 1028 | dr->handle.revisit = svc_revisit; |
1033 | return &dr->handle; | 1029 | return &dr->handle; |
@@ -1065,14 +1061,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) | |||
1065 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) | 1061 | if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) |
1066 | return NULL; | 1062 | return NULL; |
1067 | spin_lock(&xprt->xpt_lock); | 1063 | spin_lock(&xprt->xpt_lock); |
1068 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); | ||
1069 | if (!list_empty(&xprt->xpt_deferred)) { | 1064 | if (!list_empty(&xprt->xpt_deferred)) { |
1070 | dr = list_entry(xprt->xpt_deferred.next, | 1065 | dr = list_entry(xprt->xpt_deferred.next, |
1071 | struct svc_deferred_req, | 1066 | struct svc_deferred_req, |
1072 | handle.recent); | 1067 | handle.recent); |
1073 | list_del_init(&dr->handle.recent); | 1068 | list_del_init(&dr->handle.recent); |
1074 | set_bit(XPT_DEFERRED, &xprt->xpt_flags); | 1069 | } else |
1075 | } | 1070 | clear_bit(XPT_DEFERRED, &xprt->xpt_flags); |
1076 | spin_unlock(&xprt->xpt_lock); | 1071 | spin_unlock(&xprt->xpt_lock); |
1077 | return dr; | 1072 | return dr; |
1078 | } | 1073 | } |
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c index 4e9393c24687..7963569fc04f 100644 --- a/net/sunrpc/svcauth.c +++ b/net/sunrpc/svcauth.c | |||
@@ -118,7 +118,6 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister); | |||
118 | 118 | ||
119 | #define DN_HASHBITS 6 | 119 | #define DN_HASHBITS 6 |
120 | #define DN_HASHMAX (1<<DN_HASHBITS) | 120 | #define DN_HASHMAX (1<<DN_HASHBITS) |
121 | #define DN_HASHMASK (DN_HASHMAX-1) | ||
122 | 121 | ||
123 | static struct hlist_head auth_domain_table[DN_HASHMAX]; | 122 | static struct hlist_head auth_domain_table[DN_HASHMAX]; |
124 | static spinlock_t auth_domain_lock = | 123 | static spinlock_t auth_domain_lock = |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 560677d187f1..30916b06c12b 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -30,7 +30,9 @@ | |||
30 | 30 | ||
31 | struct unix_domain { | 31 | struct unix_domain { |
32 | struct auth_domain h; | 32 | struct auth_domain h; |
33 | #ifdef CONFIG_NFSD_DEPRECATED | ||
33 | int addr_changes; | 34 | int addr_changes; |
35 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
34 | /* other stuff later */ | 36 | /* other stuff later */ |
35 | }; | 37 | }; |
36 | 38 | ||
@@ -64,7 +66,9 @@ struct auth_domain *unix_domain_find(char *name) | |||
64 | return NULL; | 66 | return NULL; |
65 | } | 67 | } |
66 | new->h.flavour = &svcauth_unix; | 68 | new->h.flavour = &svcauth_unix; |
69 | #ifdef CONFIG_NFSD_DEPRECATED | ||
67 | new->addr_changes = 0; | 70 | new->addr_changes = 0; |
71 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
68 | rv = auth_domain_lookup(name, &new->h); | 72 | rv = auth_domain_lookup(name, &new->h); |
69 | } | 73 | } |
70 | } | 74 | } |
@@ -85,14 +89,15 @@ static void svcauth_unix_domain_release(struct auth_domain *dom) | |||
85 | */ | 89 | */ |
86 | #define IP_HASHBITS 8 | 90 | #define IP_HASHBITS 8 |
87 | #define IP_HASHMAX (1<<IP_HASHBITS) | 91 | #define IP_HASHMAX (1<<IP_HASHBITS) |
88 | #define IP_HASHMASK (IP_HASHMAX-1) | ||
89 | 92 | ||
90 | struct ip_map { | 93 | struct ip_map { |
91 | struct cache_head h; | 94 | struct cache_head h; |
92 | char m_class[8]; /* e.g. "nfsd" */ | 95 | char m_class[8]; /* e.g. "nfsd" */ |
93 | struct in6_addr m_addr; | 96 | struct in6_addr m_addr; |
94 | struct unix_domain *m_client; | 97 | struct unix_domain *m_client; |
98 | #ifdef CONFIG_NFSD_DEPRECATED | ||
95 | int m_add_change; | 99 | int m_add_change; |
100 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
96 | }; | 101 | }; |
97 | 102 | ||
98 | static void ip_map_put(struct kref *kref) | 103 | static void ip_map_put(struct kref *kref) |
@@ -146,7 +151,9 @@ static void update(struct cache_head *cnew, struct cache_head *citem) | |||
146 | 151 | ||
147 | kref_get(&item->m_client->h.ref); | 152 | kref_get(&item->m_client->h.ref); |
148 | new->m_client = item->m_client; | 153 | new->m_client = item->m_client; |
154 | #ifdef CONFIG_NFSD_DEPRECATED | ||
149 | new->m_add_change = item->m_add_change; | 155 | new->m_add_change = item->m_add_change; |
156 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
150 | } | 157 | } |
151 | static struct cache_head *ip_map_alloc(void) | 158 | static struct cache_head *ip_map_alloc(void) |
152 | { | 159 | { |
@@ -331,6 +338,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, | |||
331 | ip.h.flags = 0; | 338 | ip.h.flags = 0; |
332 | if (!udom) | 339 | if (!udom) |
333 | set_bit(CACHE_NEGATIVE, &ip.h.flags); | 340 | set_bit(CACHE_NEGATIVE, &ip.h.flags); |
341 | #ifdef CONFIG_NFSD_DEPRECATED | ||
334 | else { | 342 | else { |
335 | ip.m_add_change = udom->addr_changes; | 343 | ip.m_add_change = udom->addr_changes; |
336 | /* if this is from the legacy set_client system call, | 344 | /* if this is from the legacy set_client system call, |
@@ -339,6 +347,7 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, | |||
339 | if (expiry == NEVER) | 347 | if (expiry == NEVER) |
340 | ip.m_add_change++; | 348 | ip.m_add_change++; |
341 | } | 349 | } |
350 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
342 | ip.h.expiry_time = expiry; | 351 | ip.h.expiry_time = expiry; |
343 | ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, | 352 | ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, |
344 | hash_str(ipm->m_class, IP_HASHBITS) ^ | 353 | hash_str(ipm->m_class, IP_HASHBITS) ^ |
@@ -358,6 +367,7 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm, | |||
358 | return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); | 367 | return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); |
359 | } | 368 | } |
360 | 369 | ||
370 | #ifdef CONFIG_NFSD_DEPRECATED | ||
361 | int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) | 371 | int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) |
362 | { | 372 | { |
363 | struct unix_domain *udom; | 373 | struct unix_domain *udom; |
@@ -402,8 +412,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) | |||
402 | return NULL; | 412 | return NULL; |
403 | 413 | ||
404 | if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { | 414 | if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { |
405 | if (test_and_set_bit(CACHE_NEGATIVE, &ipm->h.flags) == 0) | 415 | sunrpc_invalidate(&ipm->h, sn->ip_map_cache); |
406 | auth_domain_put(&ipm->m_client->h); | ||
407 | rv = NULL; | 416 | rv = NULL; |
408 | } else { | 417 | } else { |
409 | rv = &ipm->m_client->h; | 418 | rv = &ipm->m_client->h; |
@@ -413,6 +422,7 @@ struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) | |||
413 | return rv; | 422 | return rv; |
414 | } | 423 | } |
415 | EXPORT_SYMBOL_GPL(auth_unix_lookup); | 424 | EXPORT_SYMBOL_GPL(auth_unix_lookup); |
425 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
416 | 426 | ||
417 | void svcauth_unix_purge(void) | 427 | void svcauth_unix_purge(void) |
418 | { | 428 | { |
@@ -497,7 +507,6 @@ svcauth_unix_info_release(struct svc_xprt *xpt) | |||
497 | */ | 507 | */ |
498 | #define GID_HASHBITS 8 | 508 | #define GID_HASHBITS 8 |
499 | #define GID_HASHMAX (1<<GID_HASHBITS) | 509 | #define GID_HASHMAX (1<<GID_HASHBITS) |
500 | #define GID_HASHMASK (GID_HASHMAX - 1) | ||
501 | 510 | ||
502 | struct unix_gid { | 511 | struct unix_gid { |
503 | struct cache_head h; | 512 | struct cache_head h; |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 07919e16be3e..7bd3bbba4710 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -66,6 +66,13 @@ static void svc_sock_free(struct svc_xprt *); | |||
66 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 66 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, |
67 | struct net *, struct sockaddr *, | 67 | struct net *, struct sockaddr *, |
68 | int, int); | 68 | int, int); |
69 | #if defined(CONFIG_NFS_V4_1) | ||
70 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
71 | struct net *, struct sockaddr *, | ||
72 | int, int); | ||
73 | static void svc_bc_sock_free(struct svc_xprt *xprt); | ||
74 | #endif /* CONFIG_NFS_V4_1 */ | ||
75 | |||
69 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 76 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
70 | static struct lock_class_key svc_key[2]; | 77 | static struct lock_class_key svc_key[2]; |
71 | static struct lock_class_key svc_slock_key[2]; | 78 | static struct lock_class_key svc_slock_key[2]; |
@@ -324,19 +331,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen, | |||
324 | len = onelen; | 331 | len = onelen; |
325 | break; | 332 | break; |
326 | } | 333 | } |
327 | if (toclose && strcmp(toclose, buf + len) == 0) | 334 | if (toclose && strcmp(toclose, buf + len) == 0) { |
328 | closesk = svsk; | 335 | closesk = svsk; |
329 | else | 336 | svc_xprt_get(&closesk->sk_xprt); |
337 | } else | ||
330 | len += onelen; | 338 | len += onelen; |
331 | } | 339 | } |
332 | spin_unlock_bh(&serv->sv_lock); | 340 | spin_unlock_bh(&serv->sv_lock); |
333 | 341 | ||
334 | if (closesk) | 342 | if (closesk) { |
335 | /* Should unregister with portmap, but you cannot | 343 | /* Should unregister with portmap, but you cannot |
336 | * unregister just one protocol... | 344 | * unregister just one protocol... |
337 | */ | 345 | */ |
338 | svc_close_xprt(&closesk->sk_xprt); | 346 | svc_close_xprt(&closesk->sk_xprt); |
339 | else if (toclose) | 347 | svc_xprt_put(&closesk->sk_xprt); |
348 | } else if (toclose) | ||
340 | return -ENOENT; | 349 | return -ENOENT; |
341 | return len; | 350 | return len; |
342 | } | 351 | } |
@@ -985,15 +994,17 @@ static int svc_process_calldir(struct svc_sock *svsk, struct svc_rqst *rqstp, | |||
985 | vec[0] = rqstp->rq_arg.head[0]; | 994 | vec[0] = rqstp->rq_arg.head[0]; |
986 | } else { | 995 | } else { |
987 | /* REPLY */ | 996 | /* REPLY */ |
988 | if (svsk->sk_bc_xprt) | 997 | struct rpc_xprt *bc_xprt = svsk->sk_xprt.xpt_bc_xprt; |
989 | req = xprt_lookup_rqst(svsk->sk_bc_xprt, xid); | 998 | |
999 | if (bc_xprt) | ||
1000 | req = xprt_lookup_rqst(bc_xprt, xid); | ||
990 | 1001 | ||
991 | if (!req) { | 1002 | if (!req) { |
992 | printk(KERN_NOTICE | 1003 | printk(KERN_NOTICE |
993 | "%s: Got unrecognized reply: " | 1004 | "%s: Got unrecognized reply: " |
994 | "calldir 0x%x sk_bc_xprt %p xid %08x\n", | 1005 | "calldir 0x%x xpt_bc_xprt %p xid %08x\n", |
995 | __func__, ntohl(calldir), | 1006 | __func__, ntohl(calldir), |
996 | svsk->sk_bc_xprt, xid); | 1007 | bc_xprt, xid); |
997 | vec[0] = rqstp->rq_arg.head[0]; | 1008 | vec[0] = rqstp->rq_arg.head[0]; |
998 | goto out; | 1009 | goto out; |
999 | } | 1010 | } |
@@ -1184,6 +1195,57 @@ static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, | |||
1184 | return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); | 1195 | return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); |
1185 | } | 1196 | } |
1186 | 1197 | ||
1198 | #if defined(CONFIG_NFS_V4_1) | ||
1199 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | ||
1200 | struct net *, struct sockaddr *, | ||
1201 | int, int); | ||
1202 | static void svc_bc_sock_free(struct svc_xprt *xprt); | ||
1203 | |||
1204 | static struct svc_xprt *svc_bc_tcp_create(struct svc_serv *serv, | ||
1205 | struct net *net, | ||
1206 | struct sockaddr *sa, int salen, | ||
1207 | int flags) | ||
1208 | { | ||
1209 | return svc_bc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); | ||
1210 | } | ||
1211 | |||
1212 | static void svc_bc_tcp_sock_detach(struct svc_xprt *xprt) | ||
1213 | { | ||
1214 | } | ||
1215 | |||
1216 | static struct svc_xprt_ops svc_tcp_bc_ops = { | ||
1217 | .xpo_create = svc_bc_tcp_create, | ||
1218 | .xpo_detach = svc_bc_tcp_sock_detach, | ||
1219 | .xpo_free = svc_bc_sock_free, | ||
1220 | .xpo_prep_reply_hdr = svc_tcp_prep_reply_hdr, | ||
1221 | }; | ||
1222 | |||
1223 | static struct svc_xprt_class svc_tcp_bc_class = { | ||
1224 | .xcl_name = "tcp-bc", | ||
1225 | .xcl_owner = THIS_MODULE, | ||
1226 | .xcl_ops = &svc_tcp_bc_ops, | ||
1227 | .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP, | ||
1228 | }; | ||
1229 | |||
1230 | static void svc_init_bc_xprt_sock(void) | ||
1231 | { | ||
1232 | svc_reg_xprt_class(&svc_tcp_bc_class); | ||
1233 | } | ||
1234 | |||
1235 | static void svc_cleanup_bc_xprt_sock(void) | ||
1236 | { | ||
1237 | svc_unreg_xprt_class(&svc_tcp_bc_class); | ||
1238 | } | ||
1239 | #else /* CONFIG_NFS_V4_1 */ | ||
1240 | static void svc_init_bc_xprt_sock(void) | ||
1241 | { | ||
1242 | } | ||
1243 | |||
1244 | static void svc_cleanup_bc_xprt_sock(void) | ||
1245 | { | ||
1246 | } | ||
1247 | #endif /* CONFIG_NFS_V4_1 */ | ||
1248 | |||
1187 | static struct svc_xprt_ops svc_tcp_ops = { | 1249 | static struct svc_xprt_ops svc_tcp_ops = { |
1188 | .xpo_create = svc_tcp_create, | 1250 | .xpo_create = svc_tcp_create, |
1189 | .xpo_recvfrom = svc_tcp_recvfrom, | 1251 | .xpo_recvfrom = svc_tcp_recvfrom, |
@@ -1207,12 +1269,14 @@ void svc_init_xprt_sock(void) | |||
1207 | { | 1269 | { |
1208 | svc_reg_xprt_class(&svc_tcp_class); | 1270 | svc_reg_xprt_class(&svc_tcp_class); |
1209 | svc_reg_xprt_class(&svc_udp_class); | 1271 | svc_reg_xprt_class(&svc_udp_class); |
1272 | svc_init_bc_xprt_sock(); | ||
1210 | } | 1273 | } |
1211 | 1274 | ||
1212 | void svc_cleanup_xprt_sock(void) | 1275 | void svc_cleanup_xprt_sock(void) |
1213 | { | 1276 | { |
1214 | svc_unreg_xprt_class(&svc_tcp_class); | 1277 | svc_unreg_xprt_class(&svc_tcp_class); |
1215 | svc_unreg_xprt_class(&svc_udp_class); | 1278 | svc_unreg_xprt_class(&svc_udp_class); |
1279 | svc_cleanup_bc_xprt_sock(); | ||
1216 | } | 1280 | } |
1217 | 1281 | ||
1218 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) | 1282 | static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) |
@@ -1509,41 +1573,45 @@ static void svc_sock_free(struct svc_xprt *xprt) | |||
1509 | kfree(svsk); | 1573 | kfree(svsk); |
1510 | } | 1574 | } |
1511 | 1575 | ||
1576 | #if defined(CONFIG_NFS_V4_1) | ||
1512 | /* | 1577 | /* |
1513 | * Create a svc_xprt. | 1578 | * Create a back channel svc_xprt which shares the fore channel socket. |
1514 | * | ||
1515 | * For internal use only (e.g. nfsv4.1 backchannel). | ||
1516 | * Callers should typically use the xpo_create() method. | ||
1517 | */ | 1579 | */ |
1518 | struct svc_xprt *svc_sock_create(struct svc_serv *serv, int prot) | 1580 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv, |
1581 | int protocol, | ||
1582 | struct net *net, | ||
1583 | struct sockaddr *sin, int len, | ||
1584 | int flags) | ||
1519 | { | 1585 | { |
1520 | struct svc_sock *svsk; | 1586 | struct svc_sock *svsk; |
1521 | struct svc_xprt *xprt = NULL; | 1587 | struct svc_xprt *xprt; |
1588 | |||
1589 | if (protocol != IPPROTO_TCP) { | ||
1590 | printk(KERN_WARNING "svc: only TCP sockets" | ||
1591 | " supported on shared back channel\n"); | ||
1592 | return ERR_PTR(-EINVAL); | ||
1593 | } | ||
1522 | 1594 | ||
1523 | dprintk("svc: %s\n", __func__); | ||
1524 | svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); | 1595 | svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); |
1525 | if (!svsk) | 1596 | if (!svsk) |
1526 | goto out; | 1597 | return ERR_PTR(-ENOMEM); |
1527 | 1598 | ||
1528 | xprt = &svsk->sk_xprt; | 1599 | xprt = &svsk->sk_xprt; |
1529 | if (prot == IPPROTO_TCP) | 1600 | svc_xprt_init(&svc_tcp_bc_class, xprt, serv); |
1530 | svc_xprt_init(&svc_tcp_class, xprt, serv); | 1601 | |
1531 | else if (prot == IPPROTO_UDP) | 1602 | serv->sv_bc_xprt = xprt; |
1532 | svc_xprt_init(&svc_udp_class, xprt, serv); | 1603 | |
1533 | else | ||
1534 | BUG(); | ||
1535 | out: | ||
1536 | dprintk("svc: %s return %p\n", __func__, xprt); | ||
1537 | return xprt; | 1604 | return xprt; |
1538 | } | 1605 | } |
1539 | EXPORT_SYMBOL_GPL(svc_sock_create); | ||
1540 | 1606 | ||
1541 | /* | 1607 | /* |
1542 | * Destroy a svc_sock. | 1608 | * Free a back channel svc_sock. |
1543 | */ | 1609 | */ |
1544 | void svc_sock_destroy(struct svc_xprt *xprt) | 1610 | static void svc_bc_sock_free(struct svc_xprt *xprt) |
1545 | { | 1611 | { |
1546 | if (xprt) | 1612 | if (xprt) { |
1613 | kfree(xprt->xpt_bc_sid); | ||
1547 | kfree(container_of(xprt, struct svc_sock, sk_xprt)); | 1614 | kfree(container_of(xprt, struct svc_sock, sk_xprt)); |
1615 | } | ||
1548 | } | 1616 | } |
1549 | EXPORT_SYMBOL_GPL(svc_sock_destroy); | 1617 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index cd9e841e7492..679cd674b81d 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -552,6 +552,74 @@ void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, unsigned int b | |||
552 | } | 552 | } |
553 | EXPORT_SYMBOL_GPL(xdr_write_pages); | 553 | EXPORT_SYMBOL_GPL(xdr_write_pages); |
554 | 554 | ||
555 | static void xdr_set_iov(struct xdr_stream *xdr, struct kvec *iov, | ||
556 | __be32 *p, unsigned int len) | ||
557 | { | ||
558 | if (len > iov->iov_len) | ||
559 | len = iov->iov_len; | ||
560 | if (p == NULL) | ||
561 | p = (__be32*)iov->iov_base; | ||
562 | xdr->p = p; | ||
563 | xdr->end = (__be32*)(iov->iov_base + len); | ||
564 | xdr->iov = iov; | ||
565 | xdr->page_ptr = NULL; | ||
566 | } | ||
567 | |||
568 | static int xdr_set_page_base(struct xdr_stream *xdr, | ||
569 | unsigned int base, unsigned int len) | ||
570 | { | ||
571 | unsigned int pgnr; | ||
572 | unsigned int maxlen; | ||
573 | unsigned int pgoff; | ||
574 | unsigned int pgend; | ||
575 | void *kaddr; | ||
576 | |||
577 | maxlen = xdr->buf->page_len; | ||
578 | if (base >= maxlen) | ||
579 | return -EINVAL; | ||
580 | maxlen -= base; | ||
581 | if (len > maxlen) | ||
582 | len = maxlen; | ||
583 | |||
584 | base += xdr->buf->page_base; | ||
585 | |||
586 | pgnr = base >> PAGE_SHIFT; | ||
587 | xdr->page_ptr = &xdr->buf->pages[pgnr]; | ||
588 | kaddr = page_address(*xdr->page_ptr); | ||
589 | |||
590 | pgoff = base & ~PAGE_MASK; | ||
591 | xdr->p = (__be32*)(kaddr + pgoff); | ||
592 | |||
593 | pgend = pgoff + len; | ||
594 | if (pgend > PAGE_SIZE) | ||
595 | pgend = PAGE_SIZE; | ||
596 | xdr->end = (__be32*)(kaddr + pgend); | ||
597 | xdr->iov = NULL; | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static void xdr_set_next_page(struct xdr_stream *xdr) | ||
602 | { | ||
603 | unsigned int newbase; | ||
604 | |||
605 | newbase = (1 + xdr->page_ptr - xdr->buf->pages) << PAGE_SHIFT; | ||
606 | newbase -= xdr->buf->page_base; | ||
607 | |||
608 | if (xdr_set_page_base(xdr, newbase, PAGE_SIZE) < 0) | ||
609 | xdr_set_iov(xdr, xdr->buf->tail, NULL, xdr->buf->len); | ||
610 | } | ||
611 | |||
612 | static bool xdr_set_next_buffer(struct xdr_stream *xdr) | ||
613 | { | ||
614 | if (xdr->page_ptr != NULL) | ||
615 | xdr_set_next_page(xdr); | ||
616 | else if (xdr->iov == xdr->buf->head) { | ||
617 | if (xdr_set_page_base(xdr, 0, PAGE_SIZE) < 0) | ||
618 | xdr_set_iov(xdr, xdr->buf->tail, NULL, xdr->buf->len); | ||
619 | } | ||
620 | return xdr->p != xdr->end; | ||
621 | } | ||
622 | |||
555 | /** | 623 | /** |
556 | * xdr_init_decode - Initialize an xdr_stream for decoding data. | 624 | * xdr_init_decode - Initialize an xdr_stream for decoding data. |
557 | * @xdr: pointer to xdr_stream struct | 625 | * @xdr: pointer to xdr_stream struct |
@@ -560,41 +628,67 @@ EXPORT_SYMBOL_GPL(xdr_write_pages); | |||
560 | */ | 628 | */ |
561 | void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) | 629 | void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) |
562 | { | 630 | { |
563 | struct kvec *iov = buf->head; | ||
564 | unsigned int len = iov->iov_len; | ||
565 | |||
566 | if (len > buf->len) | ||
567 | len = buf->len; | ||
568 | xdr->buf = buf; | 631 | xdr->buf = buf; |
569 | xdr->iov = iov; | 632 | xdr->scratch.iov_base = NULL; |
570 | xdr->p = p; | 633 | xdr->scratch.iov_len = 0; |
571 | xdr->end = (__be32 *)((char *)iov->iov_base + len); | 634 | if (buf->head[0].iov_len != 0) |
635 | xdr_set_iov(xdr, buf->head, p, buf->len); | ||
636 | else if (buf->page_len != 0) | ||
637 | xdr_set_page_base(xdr, 0, buf->len); | ||
572 | } | 638 | } |
573 | EXPORT_SYMBOL_GPL(xdr_init_decode); | 639 | EXPORT_SYMBOL_GPL(xdr_init_decode); |
574 | 640 | ||
575 | /** | 641 | static __be32 * __xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) |
576 | * xdr_inline_peek - Allow read-ahead in the XDR data stream | ||
577 | * @xdr: pointer to xdr_stream struct | ||
578 | * @nbytes: number of bytes of data to decode | ||
579 | * | ||
580 | * Check if the input buffer is long enough to enable us to decode | ||
581 | * 'nbytes' more bytes of data starting at the current position. | ||
582 | * If so return the current pointer without updating the current | ||
583 | * pointer position. | ||
584 | */ | ||
585 | __be32 * xdr_inline_peek(struct xdr_stream *xdr, size_t nbytes) | ||
586 | { | 642 | { |
587 | __be32 *p = xdr->p; | 643 | __be32 *p = xdr->p; |
588 | __be32 *q = p + XDR_QUADLEN(nbytes); | 644 | __be32 *q = p + XDR_QUADLEN(nbytes); |
589 | 645 | ||
590 | if (unlikely(q > xdr->end || q < p)) | 646 | if (unlikely(q > xdr->end || q < p)) |
591 | return NULL; | 647 | return NULL; |
648 | xdr->p = q; | ||
592 | return p; | 649 | return p; |
593 | } | 650 | } |
594 | EXPORT_SYMBOL_GPL(xdr_inline_peek); | ||
595 | 651 | ||
596 | /** | 652 | /** |
597 | * xdr_inline_decode - Retrieve non-page XDR data to decode | 653 | * xdr_set_scratch_buffer - Attach a scratch buffer for decoding data. |
654 | * @xdr: pointer to xdr_stream struct | ||
655 | * @buf: pointer to an empty buffer | ||
656 | * @buflen: size of 'buf' | ||
657 | * | ||
658 | * The scratch buffer is used when decoding from an array of pages. | ||
659 | * If an xdr_inline_decode() call spans across page boundaries, then | ||
660 | * we copy the data into the scratch buffer in order to allow linear | ||
661 | * access. | ||
662 | */ | ||
663 | void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen) | ||
664 | { | ||
665 | xdr->scratch.iov_base = buf; | ||
666 | xdr->scratch.iov_len = buflen; | ||
667 | } | ||
668 | EXPORT_SYMBOL_GPL(xdr_set_scratch_buffer); | ||
669 | |||
670 | static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes) | ||
671 | { | ||
672 | __be32 *p; | ||
673 | void *cpdest = xdr->scratch.iov_base; | ||
674 | size_t cplen = (char *)xdr->end - (char *)xdr->p; | ||
675 | |||
676 | if (nbytes > xdr->scratch.iov_len) | ||
677 | return NULL; | ||
678 | memcpy(cpdest, xdr->p, cplen); | ||
679 | cpdest += cplen; | ||
680 | nbytes -= cplen; | ||
681 | if (!xdr_set_next_buffer(xdr)) | ||
682 | return NULL; | ||
683 | p = __xdr_inline_decode(xdr, nbytes); | ||
684 | if (p == NULL) | ||
685 | return NULL; | ||
686 | memcpy(cpdest, p, nbytes); | ||
687 | return xdr->scratch.iov_base; | ||
688 | } | ||
689 | |||
690 | /** | ||
691 | * xdr_inline_decode - Retrieve XDR data to decode | ||
598 | * @xdr: pointer to xdr_stream struct | 692 | * @xdr: pointer to xdr_stream struct |
599 | * @nbytes: number of bytes of data to decode | 693 | * @nbytes: number of bytes of data to decode |
600 | * | 694 | * |
@@ -605,13 +699,16 @@ EXPORT_SYMBOL_GPL(xdr_inline_peek); | |||
605 | */ | 699 | */ |
606 | __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) | 700 | __be32 * xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes) |
607 | { | 701 | { |
608 | __be32 *p = xdr->p; | 702 | __be32 *p; |
609 | __be32 *q = p + XDR_QUADLEN(nbytes); | ||
610 | 703 | ||
611 | if (unlikely(q > xdr->end || q < p)) | 704 | if (nbytes == 0) |
705 | return xdr->p; | ||
706 | if (xdr->p == xdr->end && !xdr_set_next_buffer(xdr)) | ||
612 | return NULL; | 707 | return NULL; |
613 | xdr->p = q; | 708 | p = __xdr_inline_decode(xdr, nbytes); |
614 | return p; | 709 | if (p != NULL) |
710 | return p; | ||
711 | return xdr_copy_to_scratch(xdr, nbytes); | ||
615 | } | 712 | } |
616 | EXPORT_SYMBOL_GPL(xdr_inline_decode); | 713 | EXPORT_SYMBOL_GPL(xdr_inline_decode); |
617 | 714 | ||
@@ -671,16 +768,12 @@ EXPORT_SYMBOL_GPL(xdr_read_pages); | |||
671 | */ | 768 | */ |
672 | void xdr_enter_page(struct xdr_stream *xdr, unsigned int len) | 769 | void xdr_enter_page(struct xdr_stream *xdr, unsigned int len) |
673 | { | 770 | { |
674 | char * kaddr = page_address(xdr->buf->pages[0]); | ||
675 | xdr_read_pages(xdr, len); | 771 | xdr_read_pages(xdr, len); |
676 | /* | 772 | /* |
677 | * Position current pointer at beginning of tail, and | 773 | * Position current pointer at beginning of tail, and |
678 | * set remaining message length. | 774 | * set remaining message length. |
679 | */ | 775 | */ |
680 | if (len > PAGE_CACHE_SIZE - xdr->buf->page_base) | 776 | xdr_set_page_base(xdr, 0, len); |
681 | len = PAGE_CACHE_SIZE - xdr->buf->page_base; | ||
682 | xdr->p = (__be32 *)(kaddr + xdr->buf->page_base); | ||
683 | xdr->end = (__be32 *)((char *)xdr->p + len); | ||
684 | } | 777 | } |
685 | EXPORT_SYMBOL_GPL(xdr_enter_page); | 778 | EXPORT_SYMBOL_GPL(xdr_enter_page); |
686 | 779 | ||
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 4c8f18aff7c3..856274d7e85c 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -965,6 +965,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req) | |||
965 | xprt = kzalloc(size, GFP_KERNEL); | 965 | xprt = kzalloc(size, GFP_KERNEL); |
966 | if (xprt == NULL) | 966 | if (xprt == NULL) |
967 | goto out; | 967 | goto out; |
968 | kref_init(&xprt->kref); | ||
968 | 969 | ||
969 | xprt->max_reqs = max_req; | 970 | xprt->max_reqs = max_req; |
970 | xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); | 971 | xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); |
@@ -1101,8 +1102,10 @@ found: | |||
1101 | -PTR_ERR(xprt)); | 1102 | -PTR_ERR(xprt)); |
1102 | return xprt; | 1103 | return xprt; |
1103 | } | 1104 | } |
1105 | if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state)) | ||
1106 | /* ->setup returned a pre-initialized xprt: */ | ||
1107 | return xprt; | ||
1104 | 1108 | ||
1105 | kref_init(&xprt->kref); | ||
1106 | spin_lock_init(&xprt->transport_lock); | 1109 | spin_lock_init(&xprt->transport_lock); |
1107 | spin_lock_init(&xprt->reserve_lock); | 1110 | spin_lock_init(&xprt->reserve_lock); |
1108 | 1111 | ||
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 96549df836ee..c431f5a57960 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -2359,6 +2359,15 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2359 | struct svc_sock *bc_sock; | 2359 | struct svc_sock *bc_sock; |
2360 | struct rpc_xprt *ret; | 2360 | struct rpc_xprt *ret; |
2361 | 2361 | ||
2362 | if (args->bc_xprt->xpt_bc_xprt) { | ||
2363 | /* | ||
2364 | * This server connection already has a backchannel | ||
2365 | * export; we can't create a new one, as we wouldn't be | ||
2366 | * able to match replies based on xid any more. So, | ||
2367 | * reuse the already-existing one: | ||
2368 | */ | ||
2369 | return args->bc_xprt->xpt_bc_xprt; | ||
2370 | } | ||
2362 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2371 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); |
2363 | if (IS_ERR(xprt)) | 2372 | if (IS_ERR(xprt)) |
2364 | return xprt; | 2373 | return xprt; |
@@ -2375,16 +2384,6 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2375 | xprt->reestablish_timeout = 0; | 2384 | xprt->reestablish_timeout = 0; |
2376 | xprt->idle_timeout = 0; | 2385 | xprt->idle_timeout = 0; |
2377 | 2386 | ||
2378 | /* | ||
2379 | * The backchannel uses the same socket connection as the | ||
2380 | * forechannel | ||
2381 | */ | ||
2382 | xprt->bc_xprt = args->bc_xprt; | ||
2383 | bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt); | ||
2384 | bc_sock->sk_bc_xprt = xprt; | ||
2385 | transport->sock = bc_sock->sk_sock; | ||
2386 | transport->inet = bc_sock->sk_sk; | ||
2387 | |||
2388 | xprt->ops = &bc_tcp_ops; | 2387 | xprt->ops = &bc_tcp_ops; |
2389 | 2388 | ||
2390 | switch (addr->sa_family) { | 2389 | switch (addr->sa_family) { |
@@ -2407,6 +2406,20 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2407 | xprt->address_strings[RPC_DISPLAY_PROTO]); | 2406 | xprt->address_strings[RPC_DISPLAY_PROTO]); |
2408 | 2407 | ||
2409 | /* | 2408 | /* |
2409 | * Once we've associated a backchannel xprt with a connection, | ||
2410 | * we want to keep it around as long as long as the connection | ||
2411 | * lasts, in case we need to start using it for a backchannel | ||
2412 | * again; this reference won't be dropped until bc_xprt is | ||
2413 | * destroyed. | ||
2414 | */ | ||
2415 | xprt_get(xprt); | ||
2416 | args->bc_xprt->xpt_bc_xprt = xprt; | ||
2417 | xprt->bc_xprt = args->bc_xprt; | ||
2418 | bc_sock = container_of(args->bc_xprt, struct svc_sock, sk_xprt); | ||
2419 | transport->sock = bc_sock->sk_sock; | ||
2420 | transport->inet = bc_sock->sk_sk; | ||
2421 | |||
2422 | /* | ||
2410 | * Since we don't want connections for the backchannel, we set | 2423 | * Since we don't want connections for the backchannel, we set |
2411 | * the xprt status to connected | 2424 | * the xprt status to connected |
2412 | */ | 2425 | */ |
@@ -2415,6 +2428,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2415 | 2428 | ||
2416 | if (try_module_get(THIS_MODULE)) | 2429 | if (try_module_get(THIS_MODULE)) |
2417 | return xprt; | 2430 | return xprt; |
2431 | xprt_put(xprt); | ||
2418 | ret = ERR_PTR(-EINVAL); | 2432 | ret = ERR_PTR(-EINVAL); |
2419 | out_err: | 2433 | out_err: |
2420 | xprt_free(xprt); | 2434 | xprt_free(xprt); |
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index d0ee29063e5d..1f1ef70f34f2 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -95,7 +95,7 @@ config CFG80211_DEBUGFS | |||
95 | If unsure, say N. | 95 | If unsure, say N. |
96 | 96 | ||
97 | config CFG80211_INTERNAL_REGDB | 97 | config CFG80211_INTERNAL_REGDB |
98 | bool "use statically compiled regulatory rules database" if EMBEDDED | 98 | bool "use statically compiled regulatory rules database" if EXPERT |
99 | default n | 99 | default n |
100 | depends on CFG80211 | 100 | depends on CFG80211 |
101 | ---help--- | 101 | ---help--- |