diff options
Diffstat (limited to 'net')
88 files changed, 839 insertions, 720 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/ax25/af_ax25.c b/net/ax25/af_ax25.c index bb86d2932394..6da5daeebab7 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1392,7 +1392,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr, | |||
1392 | ax25_cb *ax25; | 1392 | ax25_cb *ax25; |
1393 | int err = 0; | 1393 | int err = 0; |
1394 | 1394 | ||
1395 | memset(fsa, 0, sizeof(fsa)); | 1395 | memset(fsa, 0, sizeof(*fsa)); |
1396 | lock_sock(sk); | 1396 | lock_sock(sk); |
1397 | ax25 = ax25_sk(sk); | 1397 | ax25 = ax25_sk(sk); |
1398 | 1398 | ||
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index d4d9926c2201..65106fb61b8f 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -151,9 +151,9 @@ int debug_log(struct bat_priv *bat_priv, char *fmt, ...); | |||
151 | } \ | 151 | } \ |
152 | while (0) | 152 | while (0) |
153 | #else /* !CONFIG_BATMAN_ADV_DEBUG */ | 153 | #else /* !CONFIG_BATMAN_ADV_DEBUG */ |
154 | static inline void bat_dbg(char type __attribute__((unused)), | 154 | static inline void bat_dbg(char type __always_unused, |
155 | struct bat_priv *bat_priv __attribute__((unused)), | 155 | struct bat_priv *bat_priv __always_unused, |
156 | char *fmt __attribute__((unused)), ...) | 156 | char *fmt __always_unused, ...) |
157 | { | 157 | { |
158 | } | 158 | } |
159 | #endif | 159 | #endif |
diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index b49fdf70a6d5..2284e8129cb2 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h | |||
@@ -63,7 +63,7 @@ struct batman_packet { | |||
63 | uint8_t num_hna; | 63 | uint8_t num_hna; |
64 | uint8_t gw_flags; /* flags related to gateway class */ | 64 | uint8_t gw_flags; /* flags related to gateway class */ |
65 | uint8_t align; | 65 | uint8_t align; |
66 | } __attribute__((packed)); | 66 | } __packed; |
67 | 67 | ||
68 | #define BAT_PACKET_LEN sizeof(struct batman_packet) | 68 | #define BAT_PACKET_LEN sizeof(struct batman_packet) |
69 | 69 | ||
@@ -76,7 +76,7 @@ struct icmp_packet { | |||
76 | uint8_t orig[6]; | 76 | uint8_t orig[6]; |
77 | uint16_t seqno; | 77 | uint16_t seqno; |
78 | uint8_t uid; | 78 | uint8_t uid; |
79 | } __attribute__((packed)); | 79 | } __packed; |
80 | 80 | ||
81 | #define BAT_RR_LEN 16 | 81 | #define BAT_RR_LEN 16 |
82 | 82 | ||
@@ -93,14 +93,14 @@ struct icmp_packet_rr { | |||
93 | uint8_t uid; | 93 | uint8_t uid; |
94 | uint8_t rr_cur; | 94 | uint8_t rr_cur; |
95 | uint8_t rr[BAT_RR_LEN][ETH_ALEN]; | 95 | uint8_t rr[BAT_RR_LEN][ETH_ALEN]; |
96 | } __attribute__((packed)); | 96 | } __packed; |
97 | 97 | ||
98 | struct unicast_packet { | 98 | struct unicast_packet { |
99 | uint8_t packet_type; | 99 | uint8_t packet_type; |
100 | uint8_t version; /* batman version field */ | 100 | uint8_t version; /* batman version field */ |
101 | uint8_t dest[6]; | 101 | uint8_t dest[6]; |
102 | uint8_t ttl; | 102 | uint8_t ttl; |
103 | } __attribute__((packed)); | 103 | } __packed; |
104 | 104 | ||
105 | struct unicast_frag_packet { | 105 | struct unicast_frag_packet { |
106 | uint8_t packet_type; | 106 | uint8_t packet_type; |
@@ -110,7 +110,7 @@ struct unicast_frag_packet { | |||
110 | uint8_t flags; | 110 | uint8_t flags; |
111 | uint8_t orig[6]; | 111 | uint8_t orig[6]; |
112 | uint16_t seqno; | 112 | uint16_t seqno; |
113 | } __attribute__((packed)); | 113 | } __packed; |
114 | 114 | ||
115 | struct bcast_packet { | 115 | struct bcast_packet { |
116 | uint8_t packet_type; | 116 | uint8_t packet_type; |
@@ -118,7 +118,7 @@ struct bcast_packet { | |||
118 | uint8_t orig[6]; | 118 | uint8_t orig[6]; |
119 | uint8_t ttl; | 119 | uint8_t ttl; |
120 | uint32_t seqno; | 120 | uint32_t seqno; |
121 | } __attribute__((packed)); | 121 | } __packed; |
122 | 122 | ||
123 | struct vis_packet { | 123 | struct vis_packet { |
124 | uint8_t packet_type; | 124 | uint8_t packet_type; |
@@ -131,6 +131,6 @@ struct vis_packet { | |||
131 | * neighbors */ | 131 | * neighbors */ |
132 | uint8_t target_orig[6]; /* who should receive this packet */ | 132 | uint8_t target_orig[6]; /* who should receive this packet */ |
133 | uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ | 133 | uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ |
134 | } __attribute__((packed)); | 134 | } __packed; |
135 | 135 | ||
136 | #endif /* _NET_BATMAN_ADV_PACKET_H_ */ | 136 | #endif /* _NET_BATMAN_ADV_PACKET_H_ */ |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 97cb23dd3e69..bf3f6f5a12c4 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -246,13 +246,13 @@ struct vis_info { | |||
246 | /* this packet might be part of the vis send queue. */ | 246 | /* this packet might be part of the vis send queue. */ |
247 | struct sk_buff *skb_packet; | 247 | struct sk_buff *skb_packet; |
248 | /* vis_info may follow here*/ | 248 | /* vis_info may follow here*/ |
249 | } __attribute__((packed)); | 249 | } __packed; |
250 | 250 | ||
251 | struct vis_info_entry { | 251 | struct vis_info_entry { |
252 | uint8_t src[ETH_ALEN]; | 252 | uint8_t src[ETH_ALEN]; |
253 | uint8_t dest[ETH_ALEN]; | 253 | uint8_t dest[ETH_ALEN]; |
254 | uint8_t quality; /* quality = 0 means HNA */ | 254 | uint8_t quality; /* quality = 0 means HNA */ |
255 | } __attribute__((packed)); | 255 | } __packed; |
256 | 256 | ||
257 | struct recvlist_node { | 257 | struct recvlist_node { |
258 | struct list_head list; | 258 | struct list_head list; |
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index dc2e28bed844..ee41fef04b21 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c | |||
@@ -229,10 +229,12 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, | |||
229 | if (!bat_priv->primary_if) | 229 | if (!bat_priv->primary_if) |
230 | goto dropped; | 230 | goto dropped; |
231 | 231 | ||
232 | unicast_packet = (struct unicast_packet *) skb->data; | 232 | frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); |
233 | if (!frag_skb) | ||
234 | goto dropped; | ||
233 | 235 | ||
236 | unicast_packet = (struct unicast_packet *) skb->data; | ||
234 | memcpy(&tmp_uc, unicast_packet, uc_hdr_len); | 237 | memcpy(&tmp_uc, unicast_packet, uc_hdr_len); |
235 | frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); | ||
236 | skb_split(skb, frag_skb, data_len / 2); | 238 | skb_split(skb, frag_skb, data_len / 2); |
237 | 239 | ||
238 | if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || | 240 | if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 1bf0cf503796..8184c031d028 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -740,12 +740,12 @@ static int setsockopt(struct socket *sock, | |||
740 | if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL) | 740 | if (cf_sk->sk.sk_protocol != CAIFPROTO_UTIL) |
741 | return -ENOPROTOOPT; | 741 | return -ENOPROTOOPT; |
742 | lock_sock(&(cf_sk->sk)); | 742 | lock_sock(&(cf_sk->sk)); |
743 | cf_sk->conn_req.param.size = ol; | ||
744 | if (ol > sizeof(cf_sk->conn_req.param.data) || | 743 | if (ol > sizeof(cf_sk->conn_req.param.data) || |
745 | copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) { | 744 | copy_from_user(&cf_sk->conn_req.param.data, ov, ol)) { |
746 | release_sock(&cf_sk->sk); | 745 | release_sock(&cf_sk->sk); |
747 | return -EINVAL; | 746 | return -EINVAL; |
748 | } | 747 | } |
748 | cf_sk->conn_req.param.size = ol; | ||
749 | release_sock(&cf_sk->sk); | 749 | release_sock(&cf_sk->sk); |
750 | return 0; | 750 | return 0; |
751 | 751 | ||
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 21ede141018a..c665de778b60 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
@@ -191,6 +191,7 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) | |||
191 | struct cflayer *servl = NULL; | 191 | struct cflayer *servl = NULL; |
192 | struct cfcnfg_phyinfo *phyinfo = NULL; | 192 | struct cfcnfg_phyinfo *phyinfo = NULL; |
193 | u8 phyid = 0; | 193 | u8 phyid = 0; |
194 | |||
194 | caif_assert(adap_layer != NULL); | 195 | caif_assert(adap_layer != NULL); |
195 | channel_id = adap_layer->id; | 196 | channel_id = adap_layer->id; |
196 | if (adap_layer->dn == NULL || channel_id == 0) { | 197 | if (adap_layer->dn == NULL || channel_id == 0) { |
@@ -199,16 +200,16 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) | |||
199 | goto end; | 200 | goto end; |
200 | } | 201 | } |
201 | servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id); | 202 | servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id); |
202 | if (servl == NULL) | ||
203 | goto end; | ||
204 | layer_set_up(servl, NULL); | ||
205 | ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); | ||
206 | if (servl == NULL) { | 203 | if (servl == NULL) { |
207 | pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)", | 204 | pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)", |
208 | channel_id); | 205 | channel_id); |
209 | ret = -EINVAL; | 206 | ret = -EINVAL; |
210 | goto end; | 207 | goto end; |
211 | } | 208 | } |
209 | layer_set_up(servl, NULL); | ||
210 | ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); | ||
211 | if (ret) | ||
212 | goto end; | ||
212 | caif_assert(channel_id == servl->id); | 213 | caif_assert(channel_id == servl->id); |
213 | if (adap_layer->dn != NULL) { | 214 | if (adap_layer->dn != NULL) { |
214 | phyid = cfsrvl_getphyid(adap_layer->dn); | 215 | phyid = cfsrvl_getphyid(adap_layer->dn); |
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 84a422c98941..fa9dab372b68 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
@@ -76,6 +76,8 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) | |||
76 | struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); | 76 | struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); |
77 | int pktlen; | 77 | int pktlen; |
78 | int err = 0; | 78 | int err = 0; |
79 | const u8 *ip_version; | ||
80 | u8 buf; | ||
79 | 81 | ||
80 | priv = container_of(layr, struct chnl_net, chnl); | 82 | priv = container_of(layr, struct chnl_net, chnl); |
81 | 83 | ||
@@ -90,7 +92,21 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) | |||
90 | * send the packet to the net stack. | 92 | * send the packet to the net stack. |
91 | */ | 93 | */ |
92 | skb->dev = priv->netdev; | 94 | skb->dev = priv->netdev; |
93 | skb->protocol = htons(ETH_P_IP); | 95 | |
96 | /* check the version of IP */ | ||
97 | ip_version = skb_header_pointer(skb, 0, 1, &buf); | ||
98 | if (!ip_version) | ||
99 | return -EINVAL; | ||
100 | switch (*ip_version >> 4) { | ||
101 | case 4: | ||
102 | skb->protocol = htons(ETH_P_IP); | ||
103 | break; | ||
104 | case 6: | ||
105 | skb->protocol = htons(ETH_P_IPV6); | ||
106 | break; | ||
107 | default: | ||
108 | return -EINVAL; | ||
109 | } | ||
94 | 110 | ||
95 | /* If we change the header in loop mode, the checksum is corrupted. */ | 111 | /* If we change the header in loop mode, the checksum is corrupted. */ |
96 | if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) | 112 | if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 9d5e8accfab1..092dc88a7c64 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -1256,6 +1256,9 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1256 | struct sockaddr_can *addr = | 1256 | struct sockaddr_can *addr = |
1257 | (struct sockaddr_can *)msg->msg_name; | 1257 | (struct sockaddr_can *)msg->msg_name; |
1258 | 1258 | ||
1259 | if (msg->msg_namelen < sizeof(*addr)) | ||
1260 | return -EINVAL; | ||
1261 | |||
1259 | if (addr->can_family != AF_CAN) | 1262 | if (addr->can_family != AF_CAN) |
1260 | return -EINVAL; | 1263 | return -EINVAL; |
1261 | 1264 | ||
diff --git a/net/can/raw.c b/net/can/raw.c index e88f610fdb7b..883e9d74fddf 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -649,6 +649,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
649 | struct sockaddr_can *addr = | 649 | struct sockaddr_can *addr = |
650 | (struct sockaddr_can *)msg->msg_name; | 650 | (struct sockaddr_can *)msg->msg_name; |
651 | 651 | ||
652 | if (msg->msg_namelen < sizeof(*addr)) | ||
653 | return -EINVAL; | ||
654 | |||
652 | if (addr->can_family != AF_CAN) | 655 | if (addr->can_family != AF_CAN) |
653 | return -EINVAL; | 656 | return -EINVAL; |
654 | 657 | ||
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 a215269d2e35..7741507429f4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1732,33 +1732,6 @@ void netif_device_attach(struct net_device *dev) | |||
1732 | } | 1732 | } |
1733 | EXPORT_SYMBOL(netif_device_attach); | 1733 | EXPORT_SYMBOL(netif_device_attach); |
1734 | 1734 | ||
1735 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) | ||
1736 | { | ||
1737 | return ((features & NETIF_F_NO_CSUM) || | ||
1738 | ((features & NETIF_F_V4_CSUM) && | ||
1739 | protocol == htons(ETH_P_IP)) || | ||
1740 | ((features & NETIF_F_V6_CSUM) && | ||
1741 | protocol == htons(ETH_P_IPV6)) || | ||
1742 | ((features & NETIF_F_FCOE_CRC) && | ||
1743 | protocol == htons(ETH_P_FCOE))); | ||
1744 | } | ||
1745 | |||
1746 | static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) | ||
1747 | { | ||
1748 | __be16 protocol = skb->protocol; | ||
1749 | int features = dev->features; | ||
1750 | |||
1751 | if (vlan_tx_tag_present(skb)) { | ||
1752 | features &= dev->vlan_features; | ||
1753 | } else if (protocol == htons(ETH_P_8021Q)) { | ||
1754 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | ||
1755 | protocol = veh->h_vlan_encapsulated_proto; | ||
1756 | features &= dev->vlan_features; | ||
1757 | } | ||
1758 | |||
1759 | return can_checksum_protocol(features, protocol); | ||
1760 | } | ||
1761 | |||
1762 | /** | 1735 | /** |
1763 | * skb_dev_set -- assign a new device to a buffer | 1736 | * skb_dev_set -- assign a new device to a buffer |
1764 | * @skb: buffer for the new device | 1737 | * @skb: buffer for the new device |
@@ -1971,16 +1944,14 @@ static void dev_gso_skb_destructor(struct sk_buff *skb) | |||
1971 | /** | 1944 | /** |
1972 | * dev_gso_segment - Perform emulated hardware segmentation on skb. | 1945 | * dev_gso_segment - Perform emulated hardware segmentation on skb. |
1973 | * @skb: buffer to segment | 1946 | * @skb: buffer to segment |
1947 | * @features: device features as applicable to this skb | ||
1974 | * | 1948 | * |
1975 | * This function segments the given skb and stores the list of segments | 1949 | * This function segments the given skb and stores the list of segments |
1976 | * in skb->next. | 1950 | * in skb->next. |
1977 | */ | 1951 | */ |
1978 | static int dev_gso_segment(struct sk_buff *skb) | 1952 | static int dev_gso_segment(struct sk_buff *skb, int features) |
1979 | { | 1953 | { |
1980 | struct net_device *dev = skb->dev; | ||
1981 | struct sk_buff *segs; | 1954 | struct sk_buff *segs; |
1982 | int features = dev->features & ~(illegal_highdma(dev, skb) ? | ||
1983 | NETIF_F_SG : 0); | ||
1984 | 1955 | ||
1985 | segs = skb_gso_segment(skb, features); | 1956 | segs = skb_gso_segment(skb, features); |
1986 | 1957 | ||
@@ -2017,22 +1988,52 @@ static inline void skb_orphan_try(struct sk_buff *skb) | |||
2017 | } | 1988 | } |
2018 | } | 1989 | } |
2019 | 1990 | ||
2020 | int netif_get_vlan_features(struct sk_buff *skb, struct net_device *dev) | 1991 | static bool can_checksum_protocol(unsigned long features, __be16 protocol) |
1992 | { | ||
1993 | return ((features & NETIF_F_GEN_CSUM) || | ||
1994 | ((features & NETIF_F_V4_CSUM) && | ||
1995 | protocol == htons(ETH_P_IP)) || | ||
1996 | ((features & NETIF_F_V6_CSUM) && | ||
1997 | protocol == htons(ETH_P_IPV6)) || | ||
1998 | ((features & NETIF_F_FCOE_CRC) && | ||
1999 | protocol == htons(ETH_P_FCOE))); | ||
2000 | } | ||
2001 | |||
2002 | static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) | ||
2003 | { | ||
2004 | if (!can_checksum_protocol(protocol, features)) { | ||
2005 | features &= ~NETIF_F_ALL_CSUM; | ||
2006 | features &= ~NETIF_F_SG; | ||
2007 | } else if (illegal_highdma(skb->dev, skb)) { | ||
2008 | features &= ~NETIF_F_SG; | ||
2009 | } | ||
2010 | |||
2011 | return features; | ||
2012 | } | ||
2013 | |||
2014 | int netif_skb_features(struct sk_buff *skb) | ||
2021 | { | 2015 | { |
2022 | __be16 protocol = skb->protocol; | 2016 | __be16 protocol = skb->protocol; |
2017 | int features = skb->dev->features; | ||
2023 | 2018 | ||
2024 | if (protocol == htons(ETH_P_8021Q)) { | 2019 | if (protocol == htons(ETH_P_8021Q)) { |
2025 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; | 2020 | struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; |
2026 | protocol = veh->h_vlan_encapsulated_proto; | 2021 | protocol = veh->h_vlan_encapsulated_proto; |
2027 | } else if (!skb->vlan_tci) | 2022 | } else if (!vlan_tx_tag_present(skb)) { |
2028 | return dev->features; | 2023 | return harmonize_features(skb, protocol, features); |
2024 | } | ||
2029 | 2025 | ||
2030 | if (protocol != htons(ETH_P_8021Q)) | 2026 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_TX); |
2031 | return dev->features & dev->vlan_features; | 2027 | |
2032 | else | 2028 | if (protocol != htons(ETH_P_8021Q)) { |
2033 | return 0; | 2029 | return harmonize_features(skb, protocol, features); |
2030 | } else { | ||
2031 | features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | | ||
2032 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_TX; | ||
2033 | return harmonize_features(skb, protocol, features); | ||
2034 | } | ||
2034 | } | 2035 | } |
2035 | EXPORT_SYMBOL(netif_get_vlan_features); | 2036 | EXPORT_SYMBOL(netif_skb_features); |
2036 | 2037 | ||
2037 | /* | 2038 | /* |
2038 | * Returns true if either: | 2039 | * Returns true if either: |
@@ -2042,22 +2043,13 @@ EXPORT_SYMBOL(netif_get_vlan_features); | |||
2042 | * support DMA from it. | 2043 | * support DMA from it. |
2043 | */ | 2044 | */ |
2044 | static inline int skb_needs_linearize(struct sk_buff *skb, | 2045 | static inline int skb_needs_linearize(struct sk_buff *skb, |
2045 | struct net_device *dev) | 2046 | int features) |
2046 | { | 2047 | { |
2047 | if (skb_is_nonlinear(skb)) { | 2048 | return skb_is_nonlinear(skb) && |
2048 | int features = dev->features; | 2049 | ((skb_has_frag_list(skb) && |
2049 | 2050 | !(features & NETIF_F_FRAGLIST)) || | |
2050 | if (vlan_tx_tag_present(skb)) | ||
2051 | features &= dev->vlan_features; | ||
2052 | |||
2053 | return (skb_has_frag_list(skb) && | ||
2054 | !(features & NETIF_F_FRAGLIST)) || | ||
2055 | (skb_shinfo(skb)->nr_frags && | 2051 | (skb_shinfo(skb)->nr_frags && |
2056 | (!(features & NETIF_F_SG) || | 2052 | !(features & NETIF_F_SG))); |
2057 | illegal_highdma(dev, skb))); | ||
2058 | } | ||
2059 | |||
2060 | return 0; | ||
2061 | } | 2053 | } |
2062 | 2054 | ||
2063 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | 2055 | int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, |
@@ -2067,6 +2059,8 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2067 | int rc = NETDEV_TX_OK; | 2059 | int rc = NETDEV_TX_OK; |
2068 | 2060 | ||
2069 | if (likely(!skb->next)) { | 2061 | if (likely(!skb->next)) { |
2062 | int features; | ||
2063 | |||
2070 | /* | 2064 | /* |
2071 | * If device doesnt need skb->dst, release it right now while | 2065 | * If device doesnt need skb->dst, release it right now while |
2072 | * its hot in this cpu cache | 2066 | * its hot in this cpu cache |
@@ -2079,8 +2073,10 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2079 | 2073 | ||
2080 | skb_orphan_try(skb); | 2074 | skb_orphan_try(skb); |
2081 | 2075 | ||
2076 | features = netif_skb_features(skb); | ||
2077 | |||
2082 | if (vlan_tx_tag_present(skb) && | 2078 | if (vlan_tx_tag_present(skb) && |
2083 | !(dev->features & NETIF_F_HW_VLAN_TX)) { | 2079 | !(features & NETIF_F_HW_VLAN_TX)) { |
2084 | skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); | 2080 | skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); |
2085 | if (unlikely(!skb)) | 2081 | if (unlikely(!skb)) |
2086 | goto out; | 2082 | goto out; |
@@ -2088,13 +2084,13 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2088 | skb->vlan_tci = 0; | 2084 | skb->vlan_tci = 0; |
2089 | } | 2085 | } |
2090 | 2086 | ||
2091 | if (netif_needs_gso(dev, skb)) { | 2087 | if (netif_needs_gso(skb, features)) { |
2092 | if (unlikely(dev_gso_segment(skb))) | 2088 | if (unlikely(dev_gso_segment(skb, features))) |
2093 | goto out_kfree_skb; | 2089 | goto out_kfree_skb; |
2094 | if (skb->next) | 2090 | if (skb->next) |
2095 | goto gso; | 2091 | goto gso; |
2096 | } else { | 2092 | } else { |
2097 | if (skb_needs_linearize(skb, dev) && | 2093 | if (skb_needs_linearize(skb, features) && |
2098 | __skb_linearize(skb)) | 2094 | __skb_linearize(skb)) |
2099 | goto out_kfree_skb; | 2095 | goto out_kfree_skb; |
2100 | 2096 | ||
@@ -2105,7 +2101,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
2105 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 2101 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
2106 | skb_set_transport_header(skb, | 2102 | skb_set_transport_header(skb, |
2107 | skb_checksum_start_offset(skb)); | 2103 | skb_checksum_start_offset(skb)); |
2108 | if (!dev_can_checksum(dev, skb) && | 2104 | if (!(features & NETIF_F_ALL_CSUM) && |
2109 | skb_checksum_help(skb)) | 2105 | skb_checksum_help(skb)) |
2110 | goto out_kfree_skb; | 2106 | goto out_kfree_skb; |
2111 | } | 2107 | } |
@@ -2301,7 +2297,10 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
2301 | */ | 2297 | */ |
2302 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE)) | 2298 | if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE)) |
2303 | skb_dst_force(skb); | 2299 | skb_dst_force(skb); |
2304 | __qdisc_update_bstats(q, skb->len); | 2300 | |
2301 | qdisc_skb_cb(skb)->pkt_len = skb->len; | ||
2302 | qdisc_bstats_update(q, skb); | ||
2303 | |||
2305 | if (sch_direct_xmit(skb, q, dev, txq, root_lock)) { | 2304 | if (sch_direct_xmit(skb, q, dev, txq, root_lock)) { |
2306 | if (unlikely(contended)) { | 2305 | if (unlikely(contended)) { |
2307 | spin_unlock(&q->busylock); | 2306 | spin_unlock(&q->busylock); |
@@ -5524,34 +5523,6 @@ void netdev_run_todo(void) | |||
5524 | } | 5523 | } |
5525 | } | 5524 | } |
5526 | 5525 | ||
5527 | /** | ||
5528 | * dev_txq_stats_fold - fold tx_queues stats | ||
5529 | * @dev: device to get statistics from | ||
5530 | * @stats: struct rtnl_link_stats64 to hold results | ||
5531 | */ | ||
5532 | void dev_txq_stats_fold(const struct net_device *dev, | ||
5533 | struct rtnl_link_stats64 *stats) | ||
5534 | { | ||
5535 | u64 tx_bytes = 0, tx_packets = 0, tx_dropped = 0; | ||
5536 | unsigned int i; | ||
5537 | struct netdev_queue *txq; | ||
5538 | |||
5539 | for (i = 0; i < dev->num_tx_queues; i++) { | ||
5540 | txq = netdev_get_tx_queue(dev, i); | ||
5541 | spin_lock_bh(&txq->_xmit_lock); | ||
5542 | tx_bytes += txq->tx_bytes; | ||
5543 | tx_packets += txq->tx_packets; | ||
5544 | tx_dropped += txq->tx_dropped; | ||
5545 | spin_unlock_bh(&txq->_xmit_lock); | ||
5546 | } | ||
5547 | if (tx_bytes || tx_packets || tx_dropped) { | ||
5548 | stats->tx_bytes = tx_bytes; | ||
5549 | stats->tx_packets = tx_packets; | ||
5550 | stats->tx_dropped = tx_dropped; | ||
5551 | } | ||
5552 | } | ||
5553 | EXPORT_SYMBOL(dev_txq_stats_fold); | ||
5554 | |||
5555 | /* Convert net_device_stats to rtnl_link_stats64. They have the same | 5526 | /* Convert net_device_stats to rtnl_link_stats64. They have the same |
5556 | * fields in the same order, with only the type differing. | 5527 | * fields in the same order, with only the type differing. |
5557 | */ | 5528 | */ |
@@ -5595,7 +5566,6 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, | |||
5595 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); | 5566 | netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); |
5596 | } else { | 5567 | } else { |
5597 | netdev_stats_to_stats64(storage, &dev->stats); | 5568 | netdev_stats_to_stats64(storage, &dev->stats); |
5598 | dev_txq_stats_fold(dev, storage); | ||
5599 | } | 5569 | } |
5600 | storage->rx_dropped += atomic_long_read(&dev->rx_dropped); | 5570 | storage->rx_dropped += atomic_long_read(&dev->rx_dropped); |
5601 | return storage; | 5571 | return storage; |
@@ -5621,18 +5591,20 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) | |||
5621 | } | 5591 | } |
5622 | 5592 | ||
5623 | /** | 5593 | /** |
5624 | * alloc_netdev_mq - allocate network device | 5594 | * alloc_netdev_mqs - allocate network device |
5625 | * @sizeof_priv: size of private data to allocate space for | 5595 | * @sizeof_priv: size of private data to allocate space for |
5626 | * @name: device name format string | 5596 | * @name: device name format string |
5627 | * @setup: callback to initialize device | 5597 | * @setup: callback to initialize device |
5628 | * @queue_count: the number of subqueues to allocate | 5598 | * @txqs: the number of TX subqueues to allocate |
5599 | * @rxqs: the number of RX subqueues to allocate | ||
5629 | * | 5600 | * |
5630 | * Allocates a struct net_device with private data area for driver use | 5601 | * Allocates a struct net_device with private data area for driver use |
5631 | * and performs basic initialization. Also allocates subquue structs | 5602 | * and performs basic initialization. Also allocates subquue structs |
5632 | * for each queue on the device at the end of the netdevice. | 5603 | * for each queue on the device. |
5633 | */ | 5604 | */ |
5634 | struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | 5605 | struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, |
5635 | void (*setup)(struct net_device *), unsigned int queue_count) | 5606 | void (*setup)(struct net_device *), |
5607 | unsigned int txqs, unsigned int rxqs) | ||
5636 | { | 5608 | { |
5637 | struct net_device *dev; | 5609 | struct net_device *dev; |
5638 | size_t alloc_size; | 5610 | size_t alloc_size; |
@@ -5640,12 +5612,20 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5640 | 5612 | ||
5641 | BUG_ON(strlen(name) >= sizeof(dev->name)); | 5613 | BUG_ON(strlen(name) >= sizeof(dev->name)); |
5642 | 5614 | ||
5643 | if (queue_count < 1) { | 5615 | if (txqs < 1) { |
5644 | pr_err("alloc_netdev: Unable to allocate device " | 5616 | pr_err("alloc_netdev: Unable to allocate device " |
5645 | "with zero queues.\n"); | 5617 | "with zero queues.\n"); |
5646 | return NULL; | 5618 | return NULL; |
5647 | } | 5619 | } |
5648 | 5620 | ||
5621 | #ifdef CONFIG_RPS | ||
5622 | if (rxqs < 1) { | ||
5623 | pr_err("alloc_netdev: Unable to allocate device " | ||
5624 | "with zero RX queues.\n"); | ||
5625 | return NULL; | ||
5626 | } | ||
5627 | #endif | ||
5628 | |||
5649 | alloc_size = sizeof(struct net_device); | 5629 | alloc_size = sizeof(struct net_device); |
5650 | if (sizeof_priv) { | 5630 | if (sizeof_priv) { |
5651 | /* ensure 32-byte alignment of private area */ | 5631 | /* ensure 32-byte alignment of private area */ |
@@ -5676,14 +5656,14 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5676 | 5656 | ||
5677 | dev_net_set(dev, &init_net); | 5657 | dev_net_set(dev, &init_net); |
5678 | 5658 | ||
5679 | dev->num_tx_queues = queue_count; | 5659 | dev->num_tx_queues = txqs; |
5680 | dev->real_num_tx_queues = queue_count; | 5660 | dev->real_num_tx_queues = txqs; |
5681 | if (netif_alloc_netdev_queues(dev)) | 5661 | if (netif_alloc_netdev_queues(dev)) |
5682 | goto free_pcpu; | 5662 | goto free_pcpu; |
5683 | 5663 | ||
5684 | #ifdef CONFIG_RPS | 5664 | #ifdef CONFIG_RPS |
5685 | dev->num_rx_queues = queue_count; | 5665 | dev->num_rx_queues = rxqs; |
5686 | dev->real_num_rx_queues = queue_count; | 5666 | dev->real_num_rx_queues = rxqs; |
5687 | if (netif_alloc_rx_queues(dev)) | 5667 | if (netif_alloc_rx_queues(dev)) |
5688 | goto free_pcpu; | 5668 | goto free_pcpu; |
5689 | #endif | 5669 | #endif |
@@ -5711,7 +5691,7 @@ free_p: | |||
5711 | kfree(p); | 5691 | kfree(p); |
5712 | return NULL; | 5692 | return NULL; |
5713 | } | 5693 | } |
5714 | EXPORT_SYMBOL(alloc_netdev_mq); | 5694 | EXPORT_SYMBOL(alloc_netdev_mqs); |
5715 | 5695 | ||
5716 | /** | 5696 | /** |
5717 | * free_netdev - free network device | 5697 | * free_netdev - free network device |
@@ -6209,7 +6189,7 @@ static void __net_exit default_device_exit(struct net *net) | |||
6209 | static void __net_exit default_device_exit_batch(struct list_head *net_list) | 6189 | static void __net_exit default_device_exit_batch(struct list_head *net_list) |
6210 | { | 6190 | { |
6211 | /* At exit all network devices most be removed from a network | 6191 | /* At exit all network devices most be removed from a network |
6212 | * namespace. Do this in the reverse order of registeration. | 6192 | * namespace. Do this in the reverse order of registration. |
6213 | * Do this across as many network namespaces as possible to | 6193 | * Do this across as many network namespaces as possible to |
6214 | * improve batching efficiency. | 6194 | * improve batching efficiency. |
6215 | */ | 6195 | */ |
diff --git a/net/core/filter.c b/net/core/filter.c index 2b27d4efdd48..afc58374ca96 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -158,7 +158,7 @@ EXPORT_SYMBOL(sk_filter); | |||
158 | /** | 158 | /** |
159 | * sk_run_filter - run a filter on a socket | 159 | * sk_run_filter - run a filter on a socket |
160 | * @skb: buffer to run the filter on | 160 | * @skb: buffer to run the filter on |
161 | * @filter: filter to apply | 161 | * @fentry: filter to apply |
162 | * | 162 | * |
163 | * Decode and apply filter instructions to the skb->data. | 163 | * Decode and apply filter instructions to the skb->data. |
164 | * Return length to keep, 0 for none. @skb is the data we are | 164 | * Return length to keep, 0 for none. @skb is the data we are |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 750db57f3bb3..a5f7535aab5b 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1820,7 +1820,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1820 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) | 1820 | if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) |
1821 | return -EPERM; | 1821 | return -EPERM; |
1822 | 1822 | ||
1823 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 1823 | if (kind == 2 && (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
1824 | struct sock *rtnl; | 1824 | struct sock *rtnl; |
1825 | rtnl_dumpit_func dumpit; | 1825 | rtnl_dumpit_func dumpit; |
1826 | 1826 | ||
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/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/dccp/dccp.h b/net/dccp/dccp.h index 45087052d894..5fdb07229017 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -426,7 +426,8 @@ static inline void dccp_update_gsr(struct sock *sk, u64 seq) | |||
426 | { | 426 | { |
427 | struct dccp_sock *dp = dccp_sk(sk); | 427 | struct dccp_sock *dp = dccp_sk(sk); |
428 | 428 | ||
429 | dp->dccps_gsr = seq; | 429 | if (after48(seq, dp->dccps_gsr)) |
430 | dp->dccps_gsr = seq; | ||
430 | /* Sequence validity window depends on remote Sequence Window (7.5.1) */ | 431 | /* Sequence validity window depends on remote Sequence Window (7.5.1) */ |
431 | dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4); | 432 | dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4); |
432 | /* | 433 | /* |
diff --git a/net/dccp/input.c b/net/dccp/input.c index 15af247ea007..8cde009e8b85 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c | |||
@@ -260,7 +260,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) | |||
260 | */ | 260 | */ |
261 | if (time_before(now, (dp->dccps_rate_last + | 261 | if (time_before(now, (dp->dccps_rate_last + |
262 | sysctl_dccp_sync_ratelimit))) | 262 | sysctl_dccp_sync_ratelimit))) |
263 | return 0; | 263 | return -1; |
264 | 264 | ||
265 | DCCP_WARN("Step 6 failed for %s packet, " | 265 | DCCP_WARN("Step 6 failed for %s packet, " |
266 | "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " | 266 | "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " |
diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c index 563943822e58..42348824ee31 100644 --- a/net/dccp/sysctl.c +++ b/net/dccp/sysctl.c | |||
@@ -21,7 +21,8 @@ | |||
21 | /* Boundary values */ | 21 | /* Boundary values */ |
22 | static int zero = 0, | 22 | static int zero = 0, |
23 | u8_max = 0xFF; | 23 | u8_max = 0xFF; |
24 | static unsigned long seqw_min = 32; | 24 | static unsigned long seqw_min = DCCPF_SEQ_WMIN, |
25 | seqw_max = 0xFFFFFFFF; /* maximum on 32 bit */ | ||
25 | 26 | ||
26 | static struct ctl_table dccp_default_table[] = { | 27 | static struct ctl_table dccp_default_table[] = { |
27 | { | 28 | { |
@@ -31,6 +32,7 @@ static struct ctl_table dccp_default_table[] = { | |||
31 | .mode = 0644, | 32 | .mode = 0644, |
32 | .proc_handler = proc_doulongvec_minmax, | 33 | .proc_handler = proc_doulongvec_minmax, |
33 | .extra1 = &seqw_min, /* RFC 4340, 7.5.2 */ | 34 | .extra1 = &seqw_min, /* RFC 4340, 7.5.2 */ |
35 | .extra2 = &seqw_max, | ||
34 | }, | 36 | }, |
35 | { | 37 | { |
36 | .procname = "rx_ccid", | 38 | .procname = "rx_ccid", |
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/ethernet/eth.c b/net/ethernet/eth.c index f00ef2f1d814..44d2b42fda56 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -347,10 +347,11 @@ void ether_setup(struct net_device *dev) | |||
347 | EXPORT_SYMBOL(ether_setup); | 347 | EXPORT_SYMBOL(ether_setup); |
348 | 348 | ||
349 | /** | 349 | /** |
350 | * alloc_etherdev_mq - Allocates and sets up an Ethernet device | 350 | * alloc_etherdev_mqs - Allocates and sets up an Ethernet device |
351 | * @sizeof_priv: Size of additional driver-private structure to be allocated | 351 | * @sizeof_priv: Size of additional driver-private structure to be allocated |
352 | * for this Ethernet device | 352 | * for this Ethernet device |
353 | * @queue_count: The number of queues this device has. | 353 | * @txqs: The number of TX queues this device has. |
354 | * @rxqs: The number of RX queues this device has. | ||
354 | * | 355 | * |
355 | * Fill in the fields of the device structure with Ethernet-generic | 356 | * Fill in the fields of the device structure with Ethernet-generic |
356 | * values. Basically does everything except registering the device. | 357 | * values. Basically does everything except registering the device. |
@@ -360,11 +361,12 @@ EXPORT_SYMBOL(ether_setup); | |||
360 | * this private data area. | 361 | * this private data area. |
361 | */ | 362 | */ |
362 | 363 | ||
363 | struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count) | 364 | struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, |
365 | unsigned int rxqs) | ||
364 | { | 366 | { |
365 | return alloc_netdev_mq(sizeof_priv, "eth%d", ether_setup, queue_count); | 367 | return alloc_netdev_mqs(sizeof_priv, "eth%d", ether_setup, txqs, rxqs); |
366 | } | 368 | } |
367 | EXPORT_SYMBOL(alloc_etherdev_mq); | 369 | EXPORT_SYMBOL(alloc_etherdev_mqs); |
368 | 370 | ||
369 | static size_t _format_mac_addr(char *buf, int buflen, | 371 | static size_t _format_mac_addr(char *buf, int buflen, |
370 | const unsigned char *addr, int len) | 372 | const unsigned char *addr, int len) |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index dcb2e18f6f8e..8949a05ac307 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -435,7 +435,9 @@ config INET_DIAG | |||
435 | ---help--- | 435 | ---help--- |
436 | Support for INET (TCP, DCCP, etc) socket monitoring interface used by | 436 | Support for INET (TCP, DCCP, etc) socket monitoring interface used by |
437 | native Linux tools such as ss. ss is included in iproute2, currently | 437 | native Linux tools such as ss. ss is included in iproute2, currently |
438 | downloadable at <http://linux-net.osdl.org/index.php/Iproute2>. | 438 | downloadable at: |
439 | |||
440 | http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 | ||
439 | 441 | ||
440 | If unsure, say Y. | 442 | If unsure, say Y. |
441 | 443 | ||
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 880a5ec6dce0..86961bec70ab 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -314,14 +314,15 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb) | |||
314 | 314 | ||
315 | skb->ip_summed = CHECKSUM_NONE; | 315 | skb->ip_summed = CHECKSUM_NONE; |
316 | 316 | ||
317 | ah = (struct ip_auth_hdr *)skb->data; | ||
318 | iph = ip_hdr(skb); | ||
319 | ihl = ip_hdrlen(skb); | ||
320 | 317 | ||
321 | if ((err = skb_cow_data(skb, 0, &trailer)) < 0) | 318 | if ((err = skb_cow_data(skb, 0, &trailer)) < 0) |
322 | goto out; | 319 | goto out; |
323 | nfrags = err; | 320 | nfrags = err; |
324 | 321 | ||
322 | ah = (struct ip_auth_hdr *)skb->data; | ||
323 | iph = ip_hdr(skb); | ||
324 | ihl = ip_hdrlen(skb); | ||
325 | |||
325 | work_iph = ah_alloc_tmp(ahash, nfrags, ihl + ahp->icv_trunc_len); | 326 | work_iph = ah_alloc_tmp(ahash, nfrags, ihl + ahp->icv_trunc_len); |
326 | if (!work_iph) | 327 | if (!work_iph) |
327 | goto out; | 328 | goto out; |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index a2fc7b961dbc..04c8b69fd426 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -1143,6 +1143,23 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) | |||
1143 | return err; | 1143 | return err; |
1144 | } | 1144 | } |
1145 | 1145 | ||
1146 | int arp_invalidate(struct net_device *dev, __be32 ip) | ||
1147 | { | ||
1148 | struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev); | ||
1149 | int err = -ENXIO; | ||
1150 | |||
1151 | if (neigh) { | ||
1152 | if (neigh->nud_state & ~NUD_NOARP) | ||
1153 | err = neigh_update(neigh, NULL, NUD_FAILED, | ||
1154 | NEIGH_UPDATE_F_OVERRIDE| | ||
1155 | NEIGH_UPDATE_F_ADMIN); | ||
1156 | neigh_release(neigh); | ||
1157 | } | ||
1158 | |||
1159 | return err; | ||
1160 | } | ||
1161 | EXPORT_SYMBOL(arp_invalidate); | ||
1162 | |||
1146 | static int arp_req_delete_public(struct net *net, struct arpreq *r, | 1163 | static int arp_req_delete_public(struct net *net, struct arpreq *r, |
1147 | struct net_device *dev) | 1164 | struct net_device *dev) |
1148 | { | 1165 | { |
@@ -1163,7 +1180,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r, | |||
1163 | { | 1180 | { |
1164 | int err; | 1181 | int err; |
1165 | __be32 ip; | 1182 | __be32 ip; |
1166 | struct neighbour *neigh; | ||
1167 | 1183 | ||
1168 | if (r->arp_flags & ATF_PUBL) | 1184 | if (r->arp_flags & ATF_PUBL) |
1169 | return arp_req_delete_public(net, r, dev); | 1185 | return arp_req_delete_public(net, r, dev); |
@@ -1181,16 +1197,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r, | |||
1181 | if (!dev) | 1197 | if (!dev) |
1182 | return -EINVAL; | 1198 | return -EINVAL; |
1183 | } | 1199 | } |
1184 | err = -ENXIO; | 1200 | return arp_invalidate(dev, ip); |
1185 | neigh = neigh_lookup(&arp_tbl, &ip, dev); | ||
1186 | if (neigh) { | ||
1187 | if (neigh->nud_state & ~NUD_NOARP) | ||
1188 | err = neigh_update(neigh, NULL, NUD_FAILED, | ||
1189 | NEIGH_UPDATE_F_OVERRIDE| | ||
1190 | NEIGH_UPDATE_F_ADMIN); | ||
1191 | neigh_release(neigh); | ||
1192 | } | ||
1193 | return err; | ||
1194 | } | 1201 | } |
1195 | 1202 | ||
1196 | /* | 1203 | /* |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 25e318153f14..97e5fb765265 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -73,7 +73,7 @@ int inet_csk_bind_conflict(const struct sock *sk, | |||
73 | !sk2->sk_bound_dev_if || | 73 | !sk2->sk_bound_dev_if || |
74 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { | 74 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { |
75 | if (!reuse || !sk2->sk_reuse || | 75 | if (!reuse || !sk2->sk_reuse || |
76 | sk2->sk_state == TCP_LISTEN) { | 76 | ((1 << sk2->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))) { |
77 | const __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2); | 77 | const __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2); |
78 | if (!sk2_rcv_saddr || !sk_rcv_saddr(sk) || | 78 | if (!sk2_rcv_saddr || !sk_rcv_saddr(sk) || |
79 | sk2_rcv_saddr == sk_rcv_saddr(sk)) | 79 | sk2_rcv_saddr == sk_rcv_saddr(sk)) |
@@ -122,7 +122,8 @@ again: | |||
122 | (tb->num_owners < smallest_size || smallest_size == -1)) { | 122 | (tb->num_owners < smallest_size || smallest_size == -1)) { |
123 | smallest_size = tb->num_owners; | 123 | smallest_size = tb->num_owners; |
124 | smallest_rover = rover; | 124 | smallest_rover = rover; |
125 | if (atomic_read(&hashinfo->bsockets) > (high - low) + 1) { | 125 | if (atomic_read(&hashinfo->bsockets) > (high - low) + 1 && |
126 | !inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb)) { | ||
126 | spin_unlock(&head->lock); | 127 | spin_unlock(&head->lock); |
127 | snum = smallest_rover; | 128 | snum = smallest_rover; |
128 | goto have_snum; | 129 | goto have_snum; |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 2ada17129fce..2746c1fa6417 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -858,7 +858,7 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
858 | nlmsg_len(nlh) < hdrlen) | 858 | nlmsg_len(nlh) < hdrlen) |
859 | return -EINVAL; | 859 | return -EINVAL; |
860 | 860 | ||
861 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 861 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
862 | if (nlmsg_attrlen(nlh, hdrlen)) { | 862 | if (nlmsg_attrlen(nlh, hdrlen)) { |
863 | struct nlattr *attr; | 863 | struct nlattr *attr; |
864 | 864 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 47e5178b998b..e95054c690c6 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -710,42 +710,25 @@ static void get_counters(const struct xt_table_info *t, | |||
710 | struct arpt_entry *iter; | 710 | struct arpt_entry *iter; |
711 | unsigned int cpu; | 711 | unsigned int cpu; |
712 | unsigned int i; | 712 | unsigned int i; |
713 | unsigned int curcpu = get_cpu(); | ||
714 | |||
715 | /* Instead of clearing (by a previous call to memset()) | ||
716 | * the counters and using adds, we set the counters | ||
717 | * with data used by 'current' CPU | ||
718 | * | ||
719 | * Bottom half has to be disabled to prevent deadlock | ||
720 | * if new softirq were to run and call ipt_do_table | ||
721 | */ | ||
722 | local_bh_disable(); | ||
723 | i = 0; | ||
724 | xt_entry_foreach(iter, t->entries[curcpu], t->size) { | ||
725 | SET_COUNTER(counters[i], iter->counters.bcnt, | ||
726 | iter->counters.pcnt); | ||
727 | ++i; | ||
728 | } | ||
729 | local_bh_enable(); | ||
730 | /* Processing counters from other cpus, we can let bottom half enabled, | ||
731 | * (preemption is disabled) | ||
732 | */ | ||
733 | 713 | ||
734 | for_each_possible_cpu(cpu) { | 714 | for_each_possible_cpu(cpu) { |
735 | if (cpu == curcpu) | 715 | seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; |
736 | continue; | 716 | |
737 | i = 0; | 717 | i = 0; |
738 | local_bh_disable(); | ||
739 | xt_info_wrlock(cpu); | ||
740 | xt_entry_foreach(iter, t->entries[cpu], t->size) { | 718 | xt_entry_foreach(iter, t->entries[cpu], t->size) { |
741 | ADD_COUNTER(counters[i], iter->counters.bcnt, | 719 | u64 bcnt, pcnt; |
742 | iter->counters.pcnt); | 720 | unsigned int start; |
721 | |||
722 | do { | ||
723 | start = read_seqbegin(lock); | ||
724 | bcnt = iter->counters.bcnt; | ||
725 | pcnt = iter->counters.pcnt; | ||
726 | } while (read_seqretry(lock, start)); | ||
727 | |||
728 | ADD_COUNTER(counters[i], bcnt, pcnt); | ||
743 | ++i; | 729 | ++i; |
744 | } | 730 | } |
745 | xt_info_wrunlock(cpu); | ||
746 | local_bh_enable(); | ||
747 | } | 731 | } |
748 | put_cpu(); | ||
749 | } | 732 | } |
750 | 733 | ||
751 | static struct xt_counters *alloc_counters(const struct xt_table *table) | 734 | static struct xt_counters *alloc_counters(const struct xt_table *table) |
@@ -759,7 +742,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) | |||
759 | * about). | 742 | * about). |
760 | */ | 743 | */ |
761 | countersize = sizeof(struct xt_counters) * private->number; | 744 | countersize = sizeof(struct xt_counters) * private->number; |
762 | counters = vmalloc(countersize); | 745 | counters = vzalloc(countersize); |
763 | 746 | ||
764 | if (counters == NULL) | 747 | if (counters == NULL) |
765 | return ERR_PTR(-ENOMEM); | 748 | return ERR_PTR(-ENOMEM); |
@@ -1008,7 +991,7 @@ static int __do_replace(struct net *net, const char *name, | |||
1008 | struct arpt_entry *iter; | 991 | struct arpt_entry *iter; |
1009 | 992 | ||
1010 | ret = 0; | 993 | ret = 0; |
1011 | counters = vmalloc(num_counters * sizeof(struct xt_counters)); | 994 | counters = vzalloc(num_counters * sizeof(struct xt_counters)); |
1012 | if (!counters) { | 995 | if (!counters) { |
1013 | ret = -ENOMEM; | 996 | ret = -ENOMEM; |
1014 | goto out; | 997 | goto out; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index c5a75d70970f..ef7d7b9680ea 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -884,42 +884,25 @@ get_counters(const struct xt_table_info *t, | |||
884 | struct ipt_entry *iter; | 884 | struct ipt_entry *iter; |
885 | unsigned int cpu; | 885 | unsigned int cpu; |
886 | unsigned int i; | 886 | unsigned int i; |
887 | unsigned int curcpu = get_cpu(); | ||
888 | |||
889 | /* Instead of clearing (by a previous call to memset()) | ||
890 | * the counters and using adds, we set the counters | ||
891 | * with data used by 'current' CPU. | ||
892 | * | ||
893 | * Bottom half has to be disabled to prevent deadlock | ||
894 | * if new softirq were to run and call ipt_do_table | ||
895 | */ | ||
896 | local_bh_disable(); | ||
897 | i = 0; | ||
898 | xt_entry_foreach(iter, t->entries[curcpu], t->size) { | ||
899 | SET_COUNTER(counters[i], iter->counters.bcnt, | ||
900 | iter->counters.pcnt); | ||
901 | ++i; | ||
902 | } | ||
903 | local_bh_enable(); | ||
904 | /* Processing counters from other cpus, we can let bottom half enabled, | ||
905 | * (preemption is disabled) | ||
906 | */ | ||
907 | 887 | ||
908 | for_each_possible_cpu(cpu) { | 888 | for_each_possible_cpu(cpu) { |
909 | if (cpu == curcpu) | 889 | seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; |
910 | continue; | 890 | |
911 | i = 0; | 891 | i = 0; |
912 | local_bh_disable(); | ||
913 | xt_info_wrlock(cpu); | ||
914 | xt_entry_foreach(iter, t->entries[cpu], t->size) { | 892 | xt_entry_foreach(iter, t->entries[cpu], t->size) { |
915 | ADD_COUNTER(counters[i], iter->counters.bcnt, | 893 | u64 bcnt, pcnt; |
916 | iter->counters.pcnt); | 894 | unsigned int start; |
895 | |||
896 | do { | ||
897 | start = read_seqbegin(lock); | ||
898 | bcnt = iter->counters.bcnt; | ||
899 | pcnt = iter->counters.pcnt; | ||
900 | } while (read_seqretry(lock, start)); | ||
901 | |||
902 | ADD_COUNTER(counters[i], bcnt, pcnt); | ||
917 | ++i; /* macro does multi eval of i */ | 903 | ++i; /* macro does multi eval of i */ |
918 | } | 904 | } |
919 | xt_info_wrunlock(cpu); | ||
920 | local_bh_enable(); | ||
921 | } | 905 | } |
922 | put_cpu(); | ||
923 | } | 906 | } |
924 | 907 | ||
925 | static struct xt_counters *alloc_counters(const struct xt_table *table) | 908 | static struct xt_counters *alloc_counters(const struct xt_table *table) |
@@ -932,7 +915,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) | |||
932 | (other than comefrom, which userspace doesn't care | 915 | (other than comefrom, which userspace doesn't care |
933 | about). */ | 916 | about). */ |
934 | countersize = sizeof(struct xt_counters) * private->number; | 917 | countersize = sizeof(struct xt_counters) * private->number; |
935 | counters = vmalloc(countersize); | 918 | counters = vzalloc(countersize); |
936 | 919 | ||
937 | if (counters == NULL) | 920 | if (counters == NULL) |
938 | return ERR_PTR(-ENOMEM); | 921 | return ERR_PTR(-ENOMEM); |
@@ -1204,7 +1187,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, | |||
1204 | struct ipt_entry *iter; | 1187 | struct ipt_entry *iter; |
1205 | 1188 | ||
1206 | ret = 0; | 1189 | ret = 0; |
1207 | counters = vmalloc(num_counters * sizeof(struct xt_counters)); | 1190 | counters = vzalloc(num_counters * sizeof(struct xt_counters)); |
1208 | if (!counters) { | 1191 | if (!counters) { |
1209 | ret = -ENOMEM; | 1192 | ret = -ENOMEM; |
1210 | goto out; | 1193 | goto out; |
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 5b189c97c2fc..24a1cf110d80 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -420,9 +420,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
420 | dev->type == ARPHRD_TUNNEL6 || | 420 | dev->type == ARPHRD_TUNNEL6 || |
421 | dev->type == ARPHRD_SIT || | 421 | dev->type == ARPHRD_SIT || |
422 | dev->type == ARPHRD_NONE) { | 422 | dev->type == ARPHRD_NONE) { |
423 | printk(KERN_INFO | ||
424 | "%s: Disabled Privacy Extensions\n", | ||
425 | dev->name); | ||
426 | ndev->cnf.use_tempaddr = -1; | 423 | ndev->cnf.use_tempaddr = -1; |
427 | } else { | 424 | } else { |
428 | in6_dev_hold(ndev); | 425 | in6_dev_hold(ndev); |
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/ah6.c b/net/ipv6/ah6.c index ee82d4ef26ce..1aba54ae53c4 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -538,14 +538,16 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
538 | if (!pskb_may_pull(skb, ah_hlen)) | 538 | if (!pskb_may_pull(skb, ah_hlen)) |
539 | goto out; | 539 | goto out; |
540 | 540 | ||
541 | ip6h = ipv6_hdr(skb); | ||
542 | |||
543 | skb_push(skb, hdr_len); | ||
544 | 541 | ||
545 | if ((err = skb_cow_data(skb, 0, &trailer)) < 0) | 542 | if ((err = skb_cow_data(skb, 0, &trailer)) < 0) |
546 | goto out; | 543 | goto out; |
547 | nfrags = err; | 544 | nfrags = err; |
548 | 545 | ||
546 | ah = (struct ip_auth_hdr *)skb->data; | ||
547 | ip6h = ipv6_hdr(skb); | ||
548 | |||
549 | skb_push(skb, hdr_len); | ||
550 | |||
549 | work_iph = ah_alloc_tmp(ahash, nfrags, hdr_len + ahp->icv_trunc_len); | 551 | work_iph = ah_alloc_tmp(ahash, nfrags, hdr_len + ahp->icv_trunc_len); |
550 | if (!work_iph) | 552 | if (!work_iph) |
551 | goto out; | 553 | goto out; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index e46305d1815a..d144e629d2b4 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -44,7 +44,7 @@ int inet6_csk_bind_conflict(const struct sock *sk, | |||
44 | !sk2->sk_bound_dev_if || | 44 | !sk2->sk_bound_dev_if || |
45 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && | 45 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && |
46 | (!sk->sk_reuse || !sk2->sk_reuse || | 46 | (!sk->sk_reuse || !sk2->sk_reuse || |
47 | sk2->sk_state == TCP_LISTEN) && | 47 | ((1 << sk2->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))) && |
48 | ipv6_rcv_saddr_equal(sk, sk2)) | 48 | ipv6_rcv_saddr_equal(sk, sk2)) |
49 | break; | 49 | break; |
50 | } | 50 | } |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 94b5bf132b2e..5f8d242be3f3 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -401,6 +401,9 @@ int ip6_forward(struct sk_buff *skb) | |||
401 | goto drop; | 401 | goto drop; |
402 | } | 402 | } |
403 | 403 | ||
404 | if (skb->pkt_type != PACKET_HOST) | ||
405 | goto drop; | ||
406 | |||
404 | skb_forward_csum(skb); | 407 | skb_forward_csum(skb); |
405 | 408 | ||
406 | /* | 409 | /* |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 0c9973a657fb..47b7b8df7fac 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -897,42 +897,25 @@ get_counters(const struct xt_table_info *t, | |||
897 | struct ip6t_entry *iter; | 897 | struct ip6t_entry *iter; |
898 | unsigned int cpu; | 898 | unsigned int cpu; |
899 | unsigned int i; | 899 | unsigned int i; |
900 | unsigned int curcpu = get_cpu(); | ||
901 | |||
902 | /* Instead of clearing (by a previous call to memset()) | ||
903 | * the counters and using adds, we set the counters | ||
904 | * with data used by 'current' CPU | ||
905 | * | ||
906 | * Bottom half has to be disabled to prevent deadlock | ||
907 | * if new softirq were to run and call ipt_do_table | ||
908 | */ | ||
909 | local_bh_disable(); | ||
910 | i = 0; | ||
911 | xt_entry_foreach(iter, t->entries[curcpu], t->size) { | ||
912 | SET_COUNTER(counters[i], iter->counters.bcnt, | ||
913 | iter->counters.pcnt); | ||
914 | ++i; | ||
915 | } | ||
916 | local_bh_enable(); | ||
917 | /* Processing counters from other cpus, we can let bottom half enabled, | ||
918 | * (preemption is disabled) | ||
919 | */ | ||
920 | 900 | ||
921 | for_each_possible_cpu(cpu) { | 901 | for_each_possible_cpu(cpu) { |
922 | if (cpu == curcpu) | 902 | seqlock_t *lock = &per_cpu(xt_info_locks, cpu).lock; |
923 | continue; | 903 | |
924 | i = 0; | 904 | i = 0; |
925 | local_bh_disable(); | ||
926 | xt_info_wrlock(cpu); | ||
927 | xt_entry_foreach(iter, t->entries[cpu], t->size) { | 905 | xt_entry_foreach(iter, t->entries[cpu], t->size) { |
928 | ADD_COUNTER(counters[i], iter->counters.bcnt, | 906 | u64 bcnt, pcnt; |
929 | iter->counters.pcnt); | 907 | unsigned int start; |
908 | |||
909 | do { | ||
910 | start = read_seqbegin(lock); | ||
911 | bcnt = iter->counters.bcnt; | ||
912 | pcnt = iter->counters.pcnt; | ||
913 | } while (read_seqretry(lock, start)); | ||
914 | |||
915 | ADD_COUNTER(counters[i], bcnt, pcnt); | ||
930 | ++i; | 916 | ++i; |
931 | } | 917 | } |
932 | xt_info_wrunlock(cpu); | ||
933 | local_bh_enable(); | ||
934 | } | 918 | } |
935 | put_cpu(); | ||
936 | } | 919 | } |
937 | 920 | ||
938 | static struct xt_counters *alloc_counters(const struct xt_table *table) | 921 | static struct xt_counters *alloc_counters(const struct xt_table *table) |
@@ -945,7 +928,7 @@ static struct xt_counters *alloc_counters(const struct xt_table *table) | |||
945 | (other than comefrom, which userspace doesn't care | 928 | (other than comefrom, which userspace doesn't care |
946 | about). */ | 929 | about). */ |
947 | countersize = sizeof(struct xt_counters) * private->number; | 930 | countersize = sizeof(struct xt_counters) * private->number; |
948 | counters = vmalloc(countersize); | 931 | counters = vzalloc(countersize); |
949 | 932 | ||
950 | if (counters == NULL) | 933 | if (counters == NULL) |
951 | return ERR_PTR(-ENOMEM); | 934 | return ERR_PTR(-ENOMEM); |
@@ -1217,7 +1200,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, | |||
1217 | struct ip6t_entry *iter; | 1200 | struct ip6t_entry *iter; |
1218 | 1201 | ||
1219 | ret = 0; | 1202 | ret = 0; |
1220 | counters = vmalloc(num_counters * sizeof(struct xt_counters)); | 1203 | counters = vzalloc(num_counters * sizeof(struct xt_counters)); |
1221 | if (!counters) { | 1204 | if (!counters) { |
1222 | ret = -ENOMEM; | 1205 | ret = -ENOMEM; |
1223 | goto out; | 1206 | goto out; |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index f138b195d657..227ca82eef72 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -185,8 +185,6 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
185 | struct ieee80211_mgmt *mgmt, | 185 | struct ieee80211_mgmt *mgmt, |
186 | size_t len) | 186 | size_t len) |
187 | { | 187 | { |
188 | struct ieee80211_hw *hw = &local->hw; | ||
189 | struct ieee80211_conf *conf = &hw->conf; | ||
190 | struct tid_ampdu_rx *tid_agg_rx; | 188 | struct tid_ampdu_rx *tid_agg_rx; |
191 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; | 189 | u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; |
192 | u8 dialog_token; | 190 | u8 dialog_token; |
@@ -231,13 +229,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
231 | goto end_no_lock; | 229 | goto end_no_lock; |
232 | } | 230 | } |
233 | /* determine default buffer size */ | 231 | /* determine default buffer size */ |
234 | if (buf_size == 0) { | 232 | if (buf_size == 0) |
235 | struct ieee80211_supported_band *sband; | 233 | buf_size = IEEE80211_MAX_AMPDU_BUF; |
236 | |||
237 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
238 | buf_size = IEEE80211_MIN_AMPDU_BUF; | ||
239 | buf_size = buf_size << sband->ht_cap.ampdu_factor; | ||
240 | } | ||
241 | 234 | ||
242 | 235 | ||
243 | /* examine state machine */ | 236 | /* examine state machine */ |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 485d36bc9a46..a46ff06d7cb8 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -39,6 +39,8 @@ module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); | |||
39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, | 39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, |
40 | "Disable 40MHz support in the 2.4GHz band"); | 40 | "Disable 40MHz support in the 2.4GHz band"); |
41 | 41 | ||
42 | static struct lock_class_key ieee80211_rx_skb_queue_class; | ||
43 | |||
42 | void ieee80211_configure_filter(struct ieee80211_local *local) | 44 | void ieee80211_configure_filter(struct ieee80211_local *local) |
43 | { | 45 | { |
44 | u64 mc; | 46 | u64 mc; |
@@ -569,7 +571,15 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
569 | spin_lock_init(&local->filter_lock); | 571 | spin_lock_init(&local->filter_lock); |
570 | spin_lock_init(&local->queue_stop_reason_lock); | 572 | spin_lock_init(&local->queue_stop_reason_lock); |
571 | 573 | ||
572 | skb_queue_head_init(&local->rx_skb_queue); | 574 | /* |
575 | * The rx_skb_queue is only accessed from tasklets, | ||
576 | * but other SKB queues are used from within IRQ | ||
577 | * context. Therefore, this one needs a different | ||
578 | * locking class so our direct, non-irq-safe use of | ||
579 | * the queue's lock doesn't throw lockdep warnings. | ||
580 | */ | ||
581 | skb_queue_head_init_class(&local->rx_skb_queue, | ||
582 | &ieee80211_rx_skb_queue_class); | ||
573 | 583 | ||
574 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 584 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
575 | 585 | ||
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 715d56c85475..61c73945bb94 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -688,25 +688,23 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) | |||
688 | struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); | 688 | struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); |
689 | u_int8_t l3proto = nfmsg->nfgen_family; | 689 | u_int8_t l3proto = nfmsg->nfgen_family; |
690 | 690 | ||
691 | rcu_read_lock(); | 691 | spin_lock_bh(&nf_conntrack_lock); |
692 | last = (struct nf_conn *)cb->args[1]; | 692 | last = (struct nf_conn *)cb->args[1]; |
693 | for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) { | 693 | for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) { |
694 | restart: | 694 | restart: |
695 | hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[cb->args[0]], | 695 | hlist_nulls_for_each_entry(h, n, &net->ct.hash[cb->args[0]], |
696 | hnnode) { | 696 | hnnode) { |
697 | if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) | 697 | if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) |
698 | continue; | 698 | continue; |
699 | ct = nf_ct_tuplehash_to_ctrack(h); | 699 | ct = nf_ct_tuplehash_to_ctrack(h); |
700 | if (!atomic_inc_not_zero(&ct->ct_general.use)) | ||
701 | continue; | ||
702 | /* Dump entries of a given L3 protocol number. | 700 | /* Dump entries of a given L3 protocol number. |
703 | * If it is not specified, ie. l3proto == 0, | 701 | * If it is not specified, ie. l3proto == 0, |
704 | * then dump everything. */ | 702 | * then dump everything. */ |
705 | if (l3proto && nf_ct_l3num(ct) != l3proto) | 703 | if (l3proto && nf_ct_l3num(ct) != l3proto) |
706 | goto releasect; | 704 | continue; |
707 | if (cb->args[1]) { | 705 | if (cb->args[1]) { |
708 | if (ct != last) | 706 | if (ct != last) |
709 | goto releasect; | 707 | continue; |
710 | cb->args[1] = 0; | 708 | cb->args[1] = 0; |
711 | } | 709 | } |
712 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, | 710 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, |
@@ -724,8 +722,6 @@ restart: | |||
724 | if (acct) | 722 | if (acct) |
725 | memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX])); | 723 | memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX])); |
726 | } | 724 | } |
727 | releasect: | ||
728 | nf_ct_put(ct); | ||
729 | } | 725 | } |
730 | if (cb->args[1]) { | 726 | if (cb->args[1]) { |
731 | cb->args[1] = 0; | 727 | cb->args[1] = 0; |
@@ -733,7 +729,7 @@ releasect: | |||
733 | } | 729 | } |
734 | } | 730 | } |
735 | out: | 731 | out: |
736 | rcu_read_unlock(); | 732 | spin_unlock_bh(&nf_conntrack_lock); |
737 | if (last) | 733 | if (last) |
738 | nf_ct_put(last); | 734 | nf_ct_put(last); |
739 | 735 | ||
@@ -971,7 +967,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
971 | u16 zone; | 967 | u16 zone; |
972 | int err; | 968 | int err; |
973 | 969 | ||
974 | if (nlh->nlmsg_flags & NLM_F_DUMP) | 970 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) |
975 | return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, | 971 | return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, |
976 | ctnetlink_done); | 972 | ctnetlink_done); |
977 | 973 | ||
@@ -1019,7 +1015,8 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, | |||
1019 | free: | 1015 | free: |
1020 | kfree_skb(skb2); | 1016 | kfree_skb(skb2); |
1021 | out: | 1017 | out: |
1022 | return err; | 1018 | /* this avoids a loop in nfnetlink. */ |
1019 | return err == -EAGAIN ? -ENOBUFS : err; | ||
1023 | } | 1020 | } |
1024 | 1021 | ||
1025 | #ifdef CONFIG_NF_NAT_NEEDED | 1022 | #ifdef CONFIG_NF_NAT_NEEDED |
@@ -1835,7 +1832,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, | |||
1835 | u16 zone; | 1832 | u16 zone; |
1836 | int err; | 1833 | int err; |
1837 | 1834 | ||
1838 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 1835 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
1839 | return netlink_dump_start(ctnl, skb, nlh, | 1836 | return netlink_dump_start(ctnl, skb, nlh, |
1840 | ctnetlink_exp_dump_table, | 1837 | ctnetlink_exp_dump_table, |
1841 | ctnetlink_exp_done); | 1838 | ctnetlink_exp_done); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index fbc2b72091e0..0a77d2ff2154 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -1355,7 +1355,8 @@ static int __init xt_init(void) | |||
1355 | 1355 | ||
1356 | for_each_possible_cpu(i) { | 1356 | for_each_possible_cpu(i) { |
1357 | struct xt_info_lock *lock = &per_cpu(xt_info_locks, i); | 1357 | struct xt_info_lock *lock = &per_cpu(xt_info_locks, i); |
1358 | spin_lock_init(&lock->lock); | 1358 | |
1359 | seqlock_init(&lock->lock); | ||
1359 | lock->readers = 0; | 1360 | lock->readers = 0; |
1360 | } | 1361 | } |
1361 | 1362 | ||
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 1781d99145e2..f83cb370292b 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -519,7 +519,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
519 | security_netlink_recv(skb, CAP_NET_ADMIN)) | 519 | security_netlink_recv(skb, CAP_NET_ADMIN)) |
520 | return -EPERM; | 520 | return -EPERM; |
521 | 521 | ||
522 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 522 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
523 | if (ops->dumpit == NULL) | 523 | if (ops->dumpit == NULL) |
524 | return -EOPNOTSUPP; | 524 | return -EOPNOTSUPP; |
525 | 525 | ||
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index fd95beb72f5d..1072b2c19d31 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c | |||
@@ -37,7 +37,7 @@ | |||
37 | /* Transport protocol registration */ | 37 | /* Transport protocol registration */ |
38 | static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly; | 38 | static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly; |
39 | 39 | ||
40 | static struct phonet_protocol *phonet_proto_get(int protocol) | 40 | static struct phonet_protocol *phonet_proto_get(unsigned int protocol) |
41 | { | 41 | { |
42 | struct phonet_protocol *pp; | 42 | struct phonet_protocol *pp; |
43 | 43 | ||
@@ -458,7 +458,7 @@ static struct packet_type phonet_packet_type __read_mostly = { | |||
458 | 458 | ||
459 | static DEFINE_MUTEX(proto_tab_lock); | 459 | static DEFINE_MUTEX(proto_tab_lock); |
460 | 460 | ||
461 | int __init_or_module phonet_proto_register(int protocol, | 461 | int __init_or_module phonet_proto_register(unsigned int protocol, |
462 | struct phonet_protocol *pp) | 462 | struct phonet_protocol *pp) |
463 | { | 463 | { |
464 | int err = 0; | 464 | int err = 0; |
@@ -481,7 +481,7 @@ int __init_or_module phonet_proto_register(int protocol, | |||
481 | } | 481 | } |
482 | EXPORT_SYMBOL(phonet_proto_register); | 482 | EXPORT_SYMBOL(phonet_proto_register); |
483 | 483 | ||
484 | void phonet_proto_unregister(int protocol, struct phonet_protocol *pp) | 484 | void phonet_proto_unregister(unsigned int protocol, struct phonet_protocol *pp) |
485 | { | 485 | { |
486 | mutex_lock(&proto_tab_lock); | 486 | mutex_lock(&proto_tab_lock); |
487 | BUG_ON(proto_tab[protocol] != pp); | 487 | BUG_ON(proto_tab[protocol] != pp); |
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 4b753ef70bb7..204055302992 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/act_csum.c b/net/sched/act_csum.c index 67dc7ce9b63a..83ddfc07e45d 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c | |||
@@ -508,8 +508,7 @@ static int tcf_csum(struct sk_buff *skb, | |||
508 | 508 | ||
509 | spin_lock(&p->tcf_lock); | 509 | spin_lock(&p->tcf_lock); |
510 | p->tcf_tm.lastuse = jiffies; | 510 | p->tcf_tm.lastuse = jiffies; |
511 | p->tcf_bstats.bytes += qdisc_pkt_len(skb); | 511 | bstats_update(&p->tcf_bstats, skb); |
512 | p->tcf_bstats.packets++; | ||
513 | action = p->tcf_action; | 512 | action = p->tcf_action; |
514 | update_flags = p->update_flags; | 513 | update_flags = p->update_flags; |
515 | spin_unlock(&p->tcf_lock); | 514 | spin_unlock(&p->tcf_lock); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 8daef9632255..c2a7c20e81c1 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -209,8 +209,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a, | |||
209 | spin_lock(&ipt->tcf_lock); | 209 | spin_lock(&ipt->tcf_lock); |
210 | 210 | ||
211 | ipt->tcf_tm.lastuse = jiffies; | 211 | ipt->tcf_tm.lastuse = jiffies; |
212 | ipt->tcf_bstats.bytes += qdisc_pkt_len(skb); | 212 | bstats_update(&ipt->tcf_bstats, skb); |
213 | ipt->tcf_bstats.packets++; | ||
214 | 213 | ||
215 | /* yes, we have to worry about both in and out dev | 214 | /* yes, we have to worry about both in and out dev |
216 | worry later - danger - this API seems to have changed | 215 | worry later - danger - this API seems to have changed |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 0c311be92827..d765067e99db 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -165,8 +165,7 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, | |||
165 | 165 | ||
166 | spin_lock(&m->tcf_lock); | 166 | spin_lock(&m->tcf_lock); |
167 | m->tcf_tm.lastuse = jiffies; | 167 | m->tcf_tm.lastuse = jiffies; |
168 | m->tcf_bstats.bytes += qdisc_pkt_len(skb); | 168 | bstats_update(&m->tcf_bstats, skb); |
169 | m->tcf_bstats.packets++; | ||
170 | 169 | ||
171 | dev = m->tcfm_dev; | 170 | dev = m->tcfm_dev; |
172 | if (!dev) { | 171 | if (!dev) { |
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 186eb837e600..178a4bd7b7cb 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c | |||
@@ -125,8 +125,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, | |||
125 | egress = p->flags & TCA_NAT_FLAG_EGRESS; | 125 | egress = p->flags & TCA_NAT_FLAG_EGRESS; |
126 | action = p->tcf_action; | 126 | action = p->tcf_action; |
127 | 127 | ||
128 | p->tcf_bstats.bytes += qdisc_pkt_len(skb); | 128 | bstats_update(&p->tcf_bstats, skb); |
129 | p->tcf_bstats.packets++; | ||
130 | 129 | ||
131 | spin_unlock(&p->tcf_lock); | 130 | spin_unlock(&p->tcf_lock); |
132 | 131 | ||
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index a0593c9640db..445bef716f77 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -187,8 +187,7 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a, | |||
187 | bad: | 187 | bad: |
188 | p->tcf_qstats.overlimits++; | 188 | p->tcf_qstats.overlimits++; |
189 | done: | 189 | done: |
190 | p->tcf_bstats.bytes += qdisc_pkt_len(skb); | 190 | bstats_update(&p->tcf_bstats, skb); |
191 | p->tcf_bstats.packets++; | ||
192 | spin_unlock(&p->tcf_lock); | 191 | spin_unlock(&p->tcf_lock); |
193 | return p->tcf_action; | 192 | return p->tcf_action; |
194 | } | 193 | } |
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 7ebf7439b478..e2f08b1e2e58 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -298,8 +298,7 @@ static int tcf_act_police(struct sk_buff *skb, struct tc_action *a, | |||
298 | 298 | ||
299 | spin_lock(&police->tcf_lock); | 299 | spin_lock(&police->tcf_lock); |
300 | 300 | ||
301 | police->tcf_bstats.bytes += qdisc_pkt_len(skb); | 301 | bstats_update(&police->tcf_bstats, skb); |
302 | police->tcf_bstats.packets++; | ||
303 | 302 | ||
304 | if (police->tcfp_ewma_rate && | 303 | if (police->tcfp_ewma_rate && |
305 | police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { | 304 | police->tcf_rate_est.bps >= police->tcfp_ewma_rate) { |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 97e84f3ee775..7287cff7af3e 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
@@ -42,8 +42,7 @@ static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result | |||
42 | 42 | ||
43 | spin_lock(&d->tcf_lock); | 43 | spin_lock(&d->tcf_lock); |
44 | d->tcf_tm.lastuse = jiffies; | 44 | d->tcf_tm.lastuse = jiffies; |
45 | d->tcf_bstats.bytes += qdisc_pkt_len(skb); | 45 | bstats_update(&d->tcf_bstats, skb); |
46 | d->tcf_bstats.packets++; | ||
47 | 46 | ||
48 | /* print policy string followed by _ then packet count | 47 | /* print policy string followed by _ then packet count |
49 | * Example if this was the 3rd packet and the string was "hello" | 48 | * Example if this was the 3rd packet and the string was "hello" |
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 66cbf4eb8855..836f5fee9e58 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
@@ -46,8 +46,7 @@ static int tcf_skbedit(struct sk_buff *skb, struct tc_action *a, | |||
46 | 46 | ||
47 | spin_lock(&d->tcf_lock); | 47 | spin_lock(&d->tcf_lock); |
48 | d->tcf_tm.lastuse = jiffies; | 48 | d->tcf_tm.lastuse = jiffies; |
49 | d->tcf_bstats.bytes += qdisc_pkt_len(skb); | 49 | bstats_update(&d->tcf_bstats, skb); |
50 | d->tcf_bstats.packets++; | ||
51 | 50 | ||
52 | if (d->flags & SKBEDIT_F_PRIORITY) | 51 | if (d->flags & SKBEDIT_F_PRIORITY) |
53 | skb->priority = d->priority; | 52 | skb->priority = d->priority; |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 282540778aa8..943d733409d0 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
@@ -422,10 +422,8 @@ drop: __maybe_unused | |||
422 | } | 422 | } |
423 | return ret; | 423 | return ret; |
424 | } | 424 | } |
425 | sch->bstats.bytes += qdisc_pkt_len(skb); | 425 | qdisc_bstats_update(sch, skb); |
426 | sch->bstats.packets++; | 426 | bstats_update(&flow->bstats, skb); |
427 | flow->bstats.bytes += qdisc_pkt_len(skb); | ||
428 | flow->bstats.packets++; | ||
429 | /* | 427 | /* |
430 | * Okay, this may seem weird. We pretend we've dropped the packet if | 428 | * Okay, this may seem weird. We pretend we've dropped the packet if |
431 | * it goes via ATM. The reason for this is that the outer qdisc | 429 | * it goes via ATM. The reason for this is that the outer qdisc |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index eb7631590865..c80d1c210c5d 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -390,8 +390,7 @@ 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 | sch->bstats.packets++; | 393 | qdisc_bstats_update(sch, skb); |
394 | sch->bstats.bytes += qdisc_pkt_len(skb); | ||
395 | cbq_mark_toplevel(q, cl); | 394 | cbq_mark_toplevel(q, cl); |
396 | if (!cl->next_alive) | 395 | if (!cl->next_alive) |
397 | cbq_activate_class(cl); | 396 | cbq_activate_class(cl); |
@@ -650,8 +649,7 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child) | |||
650 | ret = qdisc_enqueue(skb, cl->q); | 649 | ret = qdisc_enqueue(skb, cl->q); |
651 | if (ret == NET_XMIT_SUCCESS) { | 650 | if (ret == NET_XMIT_SUCCESS) { |
652 | sch->q.qlen++; | 651 | sch->q.qlen++; |
653 | sch->bstats.packets++; | 652 | qdisc_bstats_update(sch, skb); |
654 | sch->bstats.bytes += qdisc_pkt_len(skb); | ||
655 | if (!cl->next_alive) | 653 | if (!cl->next_alive) |
656 | cbq_activate_class(cl); | 654 | cbq_activate_class(cl); |
657 | return 0; | 655 | return 0; |
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index aa8b5313f8cf..de55e642eafc 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c | |||
@@ -351,7 +351,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
351 | { | 351 | { |
352 | struct drr_sched *q = qdisc_priv(sch); | 352 | struct drr_sched *q = qdisc_priv(sch); |
353 | struct drr_class *cl; | 353 | struct drr_class *cl; |
354 | unsigned int len; | ||
355 | int err; | 354 | int err; |
356 | 355 | ||
357 | cl = drr_classify(skb, sch, &err); | 356 | cl = drr_classify(skb, sch, &err); |
@@ -362,7 +361,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
362 | return err; | 361 | return err; |
363 | } | 362 | } |
364 | 363 | ||
365 | len = qdisc_pkt_len(skb); | ||
366 | err = qdisc_enqueue(skb, cl->qdisc); | 364 | err = qdisc_enqueue(skb, cl->qdisc); |
367 | if (unlikely(err != NET_XMIT_SUCCESS)) { | 365 | if (unlikely(err != NET_XMIT_SUCCESS)) { |
368 | if (net_xmit_drop_count(err)) { | 366 | if (net_xmit_drop_count(err)) { |
@@ -377,10 +375,8 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
377 | cl->deficit = cl->quantum; | 375 | cl->deficit = cl->quantum; |
378 | } | 376 | } |
379 | 377 | ||
380 | cl->bstats.packets++; | 378 | bstats_update(&cl->bstats, skb); |
381 | cl->bstats.bytes += len; | 379 | qdisc_bstats_update(sch, skb); |
382 | sch->bstats.packets++; | ||
383 | sch->bstats.bytes += len; | ||
384 | 380 | ||
385 | sch->q.qlen++; | 381 | sch->q.qlen++; |
386 | return err; | 382 | return err; |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 1d295d62bb5c..60f4bdd4408e 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -260,8 +260,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
260 | return err; | 260 | return err; |
261 | } | 261 | } |
262 | 262 | ||
263 | sch->bstats.bytes += qdisc_pkt_len(skb); | 263 | qdisc_bstats_update(sch, skb); |
264 | sch->bstats.packets++; | ||
265 | sch->q.qlen++; | 264 | sch->q.qlen++; |
266 | 265 | ||
267 | return NET_XMIT_SUCCESS; | 266 | return NET_XMIT_SUCCESS; |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 069c62b7bb36..2e45791d4f6c 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
@@ -1599,10 +1599,8 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
1599 | if (cl->qdisc->q.qlen == 1) | 1599 | if (cl->qdisc->q.qlen == 1) |
1600 | set_active(cl, qdisc_pkt_len(skb)); | 1600 | set_active(cl, qdisc_pkt_len(skb)); |
1601 | 1601 | ||
1602 | cl->bstats.packets++; | 1602 | bstats_update(&cl->bstats, skb); |
1603 | cl->bstats.bytes += qdisc_pkt_len(skb); | 1603 | qdisc_bstats_update(sch, skb); |
1604 | sch->bstats.packets++; | ||
1605 | sch->bstats.bytes += qdisc_pkt_len(skb); | ||
1606 | sch->q.qlen++; | 1604 | sch->q.qlen++; |
1607 | 1605 | ||
1608 | return NET_XMIT_SUCCESS; | 1606 | return NET_XMIT_SUCCESS; |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 01b519d6c52d..984c1b0c6836 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -569,15 +569,12 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
569 | } | 569 | } |
570 | return ret; | 570 | return ret; |
571 | } else { | 571 | } else { |
572 | cl->bstats.packets += | 572 | bstats_update(&cl->bstats, skb); |
573 | skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; | ||
574 | cl->bstats.bytes += qdisc_pkt_len(skb); | ||
575 | htb_activate(q, cl); | 573 | htb_activate(q, cl); |
576 | } | 574 | } |
577 | 575 | ||
578 | sch->q.qlen++; | 576 | sch->q.qlen++; |
579 | sch->bstats.packets += skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; | 577 | qdisc_bstats_update(sch, skb); |
580 | sch->bstats.bytes += qdisc_pkt_len(skb); | ||
581 | return NET_XMIT_SUCCESS; | 578 | return NET_XMIT_SUCCESS; |
582 | } | 579 | } |
583 | 580 | ||
@@ -648,12 +645,10 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, | |||
648 | htb_add_to_wait_tree(q, cl, diff); | 645 | htb_add_to_wait_tree(q, cl, diff); |
649 | } | 646 | } |
650 | 647 | ||
651 | /* update byte stats except for leaves which are already updated */ | 648 | /* update basic stats except for leaves which are already updated */ |
652 | if (cl->level) { | 649 | if (cl->level) |
653 | cl->bstats.bytes += bytes; | 650 | bstats_update(&cl->bstats, skb); |
654 | cl->bstats.packets += skb_is_gso(skb)? | 651 | |
655 | skb_shinfo(skb)->gso_segs:1; | ||
656 | } | ||
657 | cl = cl->parent; | 652 | cl = cl->parent; |
658 | } | 653 | } |
659 | } | 654 | } |
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index f10e34a68445..bce1665239b8 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c | |||
@@ -63,8 +63,7 @@ static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
63 | 63 | ||
64 | result = tc_classify(skb, p->filter_list, &res); | 64 | result = tc_classify(skb, p->filter_list, &res); |
65 | 65 | ||
66 | sch->bstats.packets++; | 66 | qdisc_bstats_update(sch, skb); |
67 | sch->bstats.bytes += qdisc_pkt_len(skb); | ||
68 | switch (result) { | 67 | switch (result) { |
69 | case TC_ACT_SHOT: | 68 | case TC_ACT_SHOT: |
70 | result = TC_ACT_SHOT; | 69 | result = TC_ACT_SHOT; |
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 32690deab5d0..21f13da24763 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c | |||
@@ -83,8 +83,7 @@ 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 | sch->bstats.bytes += qdisc_pkt_len(skb); | 86 | qdisc_bstats_update(sch, skb); |
87 | sch->bstats.packets++; | ||
88 | sch->q.qlen++; | 87 | sch->q.qlen++; |
89 | return NET_XMIT_SUCCESS; | 88 | return NET_XMIT_SUCCESS; |
90 | } | 89 | } |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index e5593c083a78..1c4bce863479 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -240,8 +240,7 @@ 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 | sch->bstats.bytes += qdisc_pkt_len(skb); | 243 | qdisc_bstats_update(sch, skb); |
244 | sch->bstats.packets++; | ||
245 | } else if (net_xmit_drop_count(ret)) { | 244 | } else if (net_xmit_drop_count(ret)) { |
246 | sch->qstats.drops++; | 245 | sch->qstats.drops++; |
247 | } | 246 | } |
@@ -477,8 +476,7 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) | |||
477 | __skb_queue_after(list, skb, nskb); | 476 | __skb_queue_after(list, skb, nskb); |
478 | 477 | ||
479 | sch->qstats.backlog += qdisc_pkt_len(nskb); | 478 | sch->qstats.backlog += qdisc_pkt_len(nskb); |
480 | sch->bstats.bytes += qdisc_pkt_len(nskb); | 479 | qdisc_bstats_update(sch, nskb); |
481 | sch->bstats.packets++; | ||
482 | 480 | ||
483 | return NET_XMIT_SUCCESS; | 481 | return NET_XMIT_SUCCESS; |
484 | } | 482 | } |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index b1c95bce33ce..966158d49dd1 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -84,8 +84,7 @@ 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 | sch->bstats.bytes += qdisc_pkt_len(skb); | 87 | qdisc_bstats_update(sch, skb); |
88 | sch->bstats.packets++; | ||
89 | sch->q.qlen++; | 88 | sch->q.qlen++; |
90 | return NET_XMIT_SUCCESS; | 89 | return NET_XMIT_SUCCESS; |
91 | } | 90 | } |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index a67ba3c5a0cc..a6009c5a2c97 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -94,8 +94,7 @@ 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 | sch->bstats.bytes += qdisc_pkt_len(skb); | 97 | qdisc_bstats_update(sch, skb); |
98 | sch->bstats.packets++; | ||
99 | sch->q.qlen++; | 98 | sch->q.qlen++; |
100 | } else if (net_xmit_drop_count(ret)) { | 99 | } else if (net_xmit_drop_count(ret)) { |
101 | q->stats.pdrop++; | 100 | q->stats.pdrop++; |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index d54ac94066c2..239ec53a634d 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -403,8 +403,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
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 | sch->bstats.bytes += qdisc_pkt_len(skb); | 406 | qdisc_bstats_update(sch, skb); |
407 | sch->bstats.packets++; | ||
408 | return NET_XMIT_SUCCESS; | 407 | return NET_XMIT_SUCCESS; |
409 | } | 408 | } |
410 | 409 | ||
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 641a30d64635..77565e721811 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -134,8 +134,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | sch->q.qlen++; | 136 | sch->q.qlen++; |
137 | sch->bstats.bytes += qdisc_pkt_len(skb); | 137 | qdisc_bstats_update(sch, skb); |
138 | sch->bstats.packets++; | ||
139 | return NET_XMIT_SUCCESS; | 138 | return NET_XMIT_SUCCESS; |
140 | } | 139 | } |
141 | 140 | ||
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 106479a7c94a..84ce48eadff4 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c | |||
@@ -59,6 +59,10 @@ struct teql_master | |||
59 | struct net_device *dev; | 59 | struct net_device *dev; |
60 | struct Qdisc *slaves; | 60 | struct Qdisc *slaves; |
61 | struct list_head master_list; | 61 | struct list_head master_list; |
62 | unsigned long tx_bytes; | ||
63 | unsigned long tx_packets; | ||
64 | unsigned long tx_errors; | ||
65 | unsigned long tx_dropped; | ||
62 | }; | 66 | }; |
63 | 67 | ||
64 | struct teql_sched_data | 68 | struct teql_sched_data |
@@ -83,8 +87,7 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
83 | 87 | ||
84 | if (q->q.qlen < dev->tx_queue_len) { | 88 | if (q->q.qlen < dev->tx_queue_len) { |
85 | __skb_queue_tail(&q->q, skb); | 89 | __skb_queue_tail(&q->q, skb); |
86 | sch->bstats.bytes += qdisc_pkt_len(skb); | 90 | qdisc_bstats_update(sch, skb); |
87 | sch->bstats.packets++; | ||
88 | return NET_XMIT_SUCCESS; | 91 | return NET_XMIT_SUCCESS; |
89 | } | 92 | } |
90 | 93 | ||
@@ -275,7 +278,6 @@ static inline int teql_resolve(struct sk_buff *skb, | |||
275 | static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev) | 278 | static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev) |
276 | { | 279 | { |
277 | struct teql_master *master = netdev_priv(dev); | 280 | struct teql_master *master = netdev_priv(dev); |
278 | struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); | ||
279 | struct Qdisc *start, *q; | 281 | struct Qdisc *start, *q; |
280 | int busy; | 282 | int busy; |
281 | int nores; | 283 | int nores; |
@@ -315,8 +317,8 @@ restart: | |||
315 | __netif_tx_unlock(slave_txq); | 317 | __netif_tx_unlock(slave_txq); |
316 | master->slaves = NEXT_SLAVE(q); | 318 | master->slaves = NEXT_SLAVE(q); |
317 | netif_wake_queue(dev); | 319 | netif_wake_queue(dev); |
318 | txq->tx_packets++; | 320 | master->tx_packets++; |
319 | txq->tx_bytes += length; | 321 | master->tx_bytes += length; |
320 | return NETDEV_TX_OK; | 322 | return NETDEV_TX_OK; |
321 | } | 323 | } |
322 | __netif_tx_unlock(slave_txq); | 324 | __netif_tx_unlock(slave_txq); |
@@ -343,10 +345,10 @@ restart: | |||
343 | netif_stop_queue(dev); | 345 | netif_stop_queue(dev); |
344 | return NETDEV_TX_BUSY; | 346 | return NETDEV_TX_BUSY; |
345 | } | 347 | } |
346 | dev->stats.tx_errors++; | 348 | master->tx_errors++; |
347 | 349 | ||
348 | drop: | 350 | drop: |
349 | txq->tx_dropped++; | 351 | master->tx_dropped++; |
350 | dev_kfree_skb(skb); | 352 | dev_kfree_skb(skb); |
351 | return NETDEV_TX_OK; | 353 | return NETDEV_TX_OK; |
352 | } | 354 | } |
@@ -399,6 +401,18 @@ static int teql_master_close(struct net_device *dev) | |||
399 | return 0; | 401 | return 0; |
400 | } | 402 | } |
401 | 403 | ||
404 | static struct rtnl_link_stats64 *teql_master_stats64(struct net_device *dev, | ||
405 | struct rtnl_link_stats64 *stats) | ||
406 | { | ||
407 | struct teql_master *m = netdev_priv(dev); | ||
408 | |||
409 | stats->tx_packets = m->tx_packets; | ||
410 | stats->tx_bytes = m->tx_bytes; | ||
411 | stats->tx_errors = m->tx_errors; | ||
412 | stats->tx_dropped = m->tx_dropped; | ||
413 | return stats; | ||
414 | } | ||
415 | |||
402 | static int teql_master_mtu(struct net_device *dev, int new_mtu) | 416 | static int teql_master_mtu(struct net_device *dev, int new_mtu) |
403 | { | 417 | { |
404 | struct teql_master *m = netdev_priv(dev); | 418 | struct teql_master *m = netdev_priv(dev); |
@@ -423,6 +437,7 @@ static const struct net_device_ops teql_netdev_ops = { | |||
423 | .ndo_open = teql_master_open, | 437 | .ndo_open = teql_master_open, |
424 | .ndo_stop = teql_master_close, | 438 | .ndo_stop = teql_master_close, |
425 | .ndo_start_xmit = teql_master_xmit, | 439 | .ndo_start_xmit = teql_master_xmit, |
440 | .ndo_get_stats64 = teql_master_stats64, | ||
426 | .ndo_change_mtu = teql_master_mtu, | 441 | .ndo_change_mtu = teql_master_mtu, |
427 | }; | 442 | }; |
428 | 443 | ||
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/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 8eb889510916..d5e1e0b08890 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <net/sock.h> | 26 | #include <net/sock.h> |
27 | #include <net/xfrm.h> | 27 | #include <net/xfrm.h> |
28 | #include <net/netlink.h> | 28 | #include <net/netlink.h> |
29 | #include <net/ah.h> | ||
29 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
30 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 31 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
31 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
@@ -302,7 +303,8 @@ static int attach_auth_trunc(struct xfrm_algo_auth **algpp, u8 *props, | |||
302 | algo = xfrm_aalg_get_byname(ualg->alg_name, 1); | 303 | algo = xfrm_aalg_get_byname(ualg->alg_name, 1); |
303 | if (!algo) | 304 | if (!algo) |
304 | return -ENOSYS; | 305 | return -ENOSYS; |
305 | if (ualg->alg_trunc_len > algo->uinfo.auth.icv_fullbits) | 306 | if ((ualg->alg_trunc_len / 8) > MAX_AH_AUTH_LEN || |
307 | ualg->alg_trunc_len > algo->uinfo.auth.icv_fullbits) | ||
306 | return -EINVAL; | 308 | return -EINVAL; |
307 | *props = algo->desc.sadb_alg_id; | 309 | *props = algo->desc.sadb_alg_id; |
308 | 310 | ||
@@ -2187,7 +2189,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2187 | 2189 | ||
2188 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 2190 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
2189 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && | 2191 | type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && |
2190 | (nlh->nlmsg_flags & NLM_F_DUMP)) { | 2192 | (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
2191 | if (link->dump == NULL) | 2193 | if (link->dump == NULL) |
2192 | return -EINVAL; | 2194 | return -EINVAL; |
2193 | 2195 | ||