diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-07-18 12:43:08 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-07-18 12:43:08 -0400 |
| commit | f1b0c8d3d3b5ff9c0b14bb2383a4bc38d8922bd1 (patch) | |
| tree | b7d9f439d5b99d8b03bf490d4b17156414e48d45 /net | |
| parent | d591b0a3ae25f587d0c4da1e1d1a425143590790 (diff) | |
| parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) | |
Merge branch 'linus' into x86/amd-iommu
Diffstat (limited to 'net')
76 files changed, 686 insertions, 423 deletions
diff --git a/net/802/psnap.c b/net/802/psnap.c index 31128cb92a23..ea4643931446 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
| 21 | #include <linux/in.h> | 21 | #include <linux/in.h> |
| 22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 23 | #include <linux/rculist.h> | ||
| 23 | 24 | ||
| 24 | static LIST_HEAD(snap_list); | 25 | static LIST_HEAD(snap_list); |
| 25 | static DEFINE_SPINLOCK(snap_lock); | 26 | static DEFINE_SPINLOCK(snap_lock); |
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index ab2225da0ee2..08f14f6c5fd6 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
| 28 | #include <linux/in.h> | 28 | #include <linux/in.h> |
| 29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
| 30 | #include <linux/rculist.h> | ||
| 30 | #include <net/p8022.h> | 31 | #include <net/p8022.h> |
| 31 | #include <net/arp.h> | 32 | #include <net/arp.h> |
| 32 | #include <linux/rtnetlink.h> | 33 | #include <linux/rtnetlink.h> |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 72c5976a5ce3..142060f02054 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | #include <linux/rculist.h> | ||
| 18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
| 19 | #include <linux/times.h> | 20 | #include <linux/times.h> |
| 20 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index c2397f503b0f..f38cc5317b88 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -442,12 +442,16 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 442 | 442 | ||
| 443 | void __exit br_cleanup_bridges(void) | 443 | void __exit br_cleanup_bridges(void) |
| 444 | { | 444 | { |
| 445 | struct net_device *dev, *nxt; | 445 | struct net_device *dev; |
| 446 | 446 | ||
| 447 | rtnl_lock(); | 447 | rtnl_lock(); |
| 448 | for_each_netdev_safe(&init_net, dev, nxt) | 448 | restart: |
| 449 | if (dev->priv_flags & IFF_EBRIDGE) | 449 | for_each_netdev(&init_net, dev) { |
| 450 | if (dev->priv_flags & IFF_EBRIDGE) { | ||
| 450 | del_br(dev->priv); | 451 | del_br(dev->priv); |
| 452 | goto restart; | ||
| 453 | } | ||
| 454 | } | ||
| 451 | rtnl_unlock(); | 455 | rtnl_unlock(); |
| 452 | 456 | ||
| 453 | } | 457 | } |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index e38034aa56f5..9e96ffcd29a3 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
| 14 | */ | 14 | */ |
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | #include <linux/rculist.h> | ||
| 16 | 17 | ||
| 17 | #include "br_private.h" | 18 | #include "br_private.h" |
| 18 | #include "br_private_stp.h" | 19 | #include "br_private_stp.h" |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 7e8ca2836452..484bbf6dd032 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
| @@ -205,12 +205,19 @@ static int can_create(struct net *net, struct socket *sock, int protocol) | |||
| 205 | * -ENOBUFS on full driver queue (see net_xmit_errno()) | 205 | * -ENOBUFS on full driver queue (see net_xmit_errno()) |
| 206 | * -ENOMEM when local loopback failed at calling skb_clone() | 206 | * -ENOMEM when local loopback failed at calling skb_clone() |
| 207 | * -EPERM when trying to send on a non-CAN interface | 207 | * -EPERM when trying to send on a non-CAN interface |
| 208 | * -EINVAL when the skb->data does not contain a valid CAN frame | ||
| 208 | */ | 209 | */ |
| 209 | int can_send(struct sk_buff *skb, int loop) | 210 | int can_send(struct sk_buff *skb, int loop) |
| 210 | { | 211 | { |
| 211 | struct sk_buff *newskb = NULL; | 212 | struct sk_buff *newskb = NULL; |
| 213 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
| 212 | int err; | 214 | int err; |
| 213 | 215 | ||
| 216 | if (skb->len != sizeof(struct can_frame) || cf->can_dlc > 8) { | ||
| 217 | kfree_skb(skb); | ||
| 218 | return -EINVAL; | ||
| 219 | } | ||
| 220 | |||
| 214 | if (skb->dev->type != ARPHRD_CAN) { | 221 | if (skb->dev->type != ARPHRD_CAN) { |
| 215 | kfree_skb(skb); | 222 | kfree_skb(skb); |
| 216 | return -EPERM; | 223 | return -EPERM; |
| @@ -605,6 +612,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 605 | struct packet_type *pt, struct net_device *orig_dev) | 612 | struct packet_type *pt, struct net_device *orig_dev) |
| 606 | { | 613 | { |
| 607 | struct dev_rcv_lists *d; | 614 | struct dev_rcv_lists *d; |
| 615 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
| 608 | int matches; | 616 | int matches; |
| 609 | 617 | ||
| 610 | if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) { | 618 | if (dev->type != ARPHRD_CAN || dev_net(dev) != &init_net) { |
| @@ -612,6 +620,8 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 612 | return 0; | 620 | return 0; |
| 613 | } | 621 | } |
| 614 | 622 | ||
| 623 | BUG_ON(skb->len != sizeof(struct can_frame) || cf->can_dlc > 8); | ||
| 624 | |||
| 615 | /* update statistics */ | 625 | /* update statistics */ |
| 616 | can_stats.rx_frames++; | 626 | can_stats.rx_frames++; |
| 617 | can_stats.rx_frames_delta++; | 627 | can_stats.rx_frames_delta++; |
diff --git a/net/can/bcm.c b/net/can/bcm.c index d9a3a9d13bed..72c2ce904f83 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
| @@ -298,7 +298,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, | |||
| 298 | 298 | ||
| 299 | if (head->nframes) { | 299 | if (head->nframes) { |
| 300 | /* can_frames starting here */ | 300 | /* can_frames starting here */ |
| 301 | firstframe = (struct can_frame *) skb_tail_pointer(skb); | 301 | firstframe = (struct can_frame *)skb_tail_pointer(skb); |
| 302 | 302 | ||
| 303 | memcpy(skb_put(skb, datalen), frames, datalen); | 303 | memcpy(skb_put(skb, datalen), frames, datalen); |
| 304 | 304 | ||
| @@ -826,6 +826,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
| 826 | for (i = 0; i < msg_head->nframes; i++) { | 826 | for (i = 0; i < msg_head->nframes; i++) { |
| 827 | err = memcpy_fromiovec((u8 *)&op->frames[i], | 827 | err = memcpy_fromiovec((u8 *)&op->frames[i], |
| 828 | msg->msg_iov, CFSIZ); | 828 | msg->msg_iov, CFSIZ); |
| 829 | |||
| 830 | if (op->frames[i].can_dlc > 8) | ||
| 831 | err = -EINVAL; | ||
| 832 | |||
| 829 | if (err < 0) | 833 | if (err < 0) |
| 830 | return err; | 834 | return err; |
| 831 | 835 | ||
| @@ -858,6 +862,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, | |||
| 858 | for (i = 0; i < msg_head->nframes; i++) { | 862 | for (i = 0; i < msg_head->nframes; i++) { |
| 859 | err = memcpy_fromiovec((u8 *)&op->frames[i], | 863 | err = memcpy_fromiovec((u8 *)&op->frames[i], |
| 860 | msg->msg_iov, CFSIZ); | 864 | msg->msg_iov, CFSIZ); |
| 865 | |||
| 866 | if (op->frames[i].can_dlc > 8) | ||
| 867 | err = -EINVAL; | ||
| 868 | |||
| 861 | if (err < 0) { | 869 | if (err < 0) { |
| 862 | if (op->frames != &op->sframe) | 870 | if (op->frames != &op->sframe) |
| 863 | kfree(op->frames); | 871 | kfree(op->frames); |
| @@ -1164,9 +1172,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk) | |||
| 1164 | 1172 | ||
| 1165 | skb->dev = dev; | 1173 | skb->dev = dev; |
| 1166 | skb->sk = sk; | 1174 | skb->sk = sk; |
| 1167 | can_send(skb, 1); /* send with loopback */ | 1175 | err = can_send(skb, 1); /* send with loopback */ |
| 1168 | dev_put(dev); | 1176 | dev_put(dev); |
| 1169 | 1177 | ||
| 1178 | if (err) | ||
| 1179 | return err; | ||
| 1180 | |||
| 1170 | return CFSIZ + MHSIZ; | 1181 | return CFSIZ + MHSIZ; |
| 1171 | } | 1182 | } |
| 1172 | 1183 | ||
| @@ -1185,6 +1196,10 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1185 | if (!bo->bound) | 1196 | if (!bo->bound) |
| 1186 | return -ENOTCONN; | 1197 | return -ENOTCONN; |
| 1187 | 1198 | ||
| 1199 | /* check for valid message length from userspace */ | ||
| 1200 | if (size < MHSIZ || (size - MHSIZ) % CFSIZ) | ||
| 1201 | return -EINVAL; | ||
| 1202 | |||
| 1188 | /* check for alternative ifindex for this bcm_op */ | 1203 | /* check for alternative ifindex for this bcm_op */ |
| 1189 | 1204 | ||
| 1190 | if (!ifindex && msg->msg_name) { | 1205 | if (!ifindex && msg->msg_name) { |
| @@ -1259,8 +1274,8 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1259 | break; | 1274 | break; |
| 1260 | 1275 | ||
| 1261 | case TX_SEND: | 1276 | case TX_SEND: |
| 1262 | /* we need at least one can_frame */ | 1277 | /* we need exactly one can_frame behind the msg head */ |
| 1263 | if (msg_head.nframes < 1) | 1278 | if ((msg_head.nframes != 1) || (size != CFSIZ + MHSIZ)) |
| 1264 | ret = -EINVAL; | 1279 | ret = -EINVAL; |
| 1265 | else | 1280 | else |
| 1266 | ret = bcm_tx_send(msg, ifindex, sk); | 1281 | ret = bcm_tx_send(msg, ifindex, sk); |
diff --git a/net/can/raw.c b/net/can/raw.c index 69877b8e7e9c..3e46ee36a1aa 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -632,6 +632,9 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 632 | } else | 632 | } else |
| 633 | ifindex = ro->ifindex; | 633 | ifindex = ro->ifindex; |
| 634 | 634 | ||
| 635 | if (size != sizeof(struct can_frame)) | ||
| 636 | return -EINVAL; | ||
| 637 | |||
| 635 | dev = dev_get_by_index(&init_net, ifindex); | 638 | dev = dev_get_by_index(&init_net, ifindex); |
| 636 | if (!dev) | 639 | if (!dev) |
| 637 | return -ENXIO; | 640 | return -ENXIO; |
diff --git a/net/core/dev.c b/net/core/dev.c index c421a1f8f0b9..821cb1628e5e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -454,7 +454,7 @@ static int netdev_boot_setup_add(char *name, struct ifmap *map) | |||
| 454 | for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { | 454 | for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { |
| 455 | if (s[i].name[0] == '\0' || s[i].name[0] == ' ') { | 455 | if (s[i].name[0] == '\0' || s[i].name[0] == ' ') { |
| 456 | memset(s[i].name, 0, sizeof(s[i].name)); | 456 | memset(s[i].name, 0, sizeof(s[i].name)); |
| 457 | strcpy(s[i].name, name); | 457 | strlcpy(s[i].name, name, IFNAMSIZ); |
| 458 | memcpy(&s[i].map, map, sizeof(s[i].map)); | 458 | memcpy(&s[i].map, map, sizeof(s[i].map)); |
| 459 | break; | 459 | break; |
| 460 | } | 460 | } |
| @@ -479,7 +479,7 @@ int netdev_boot_setup_check(struct net_device *dev) | |||
| 479 | 479 | ||
| 480 | for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { | 480 | for (i = 0; i < NETDEV_BOOT_SETUP_MAX; i++) { |
| 481 | if (s[i].name[0] != '\0' && s[i].name[0] != ' ' && | 481 | if (s[i].name[0] != '\0' && s[i].name[0] != ' ' && |
| 482 | !strncmp(dev->name, s[i].name, strlen(s[i].name))) { | 482 | !strcmp(dev->name, s[i].name)) { |
| 483 | dev->irq = s[i].map.irq; | 483 | dev->irq = s[i].map.irq; |
| 484 | dev->base_addr = s[i].map.base_addr; | 484 | dev->base_addr = s[i].map.base_addr; |
| 485 | dev->mem_start = s[i].map.mem_start; | 485 | dev->mem_start = s[i].map.mem_start; |
| @@ -2973,7 +2973,7 @@ EXPORT_SYMBOL(dev_unicast_delete); | |||
| 2973 | /** | 2973 | /** |
| 2974 | * dev_unicast_add - add a secondary unicast address | 2974 | * dev_unicast_add - add a secondary unicast address |
| 2975 | * @dev: device | 2975 | * @dev: device |
| 2976 | * @addr: address to delete | 2976 | * @addr: address to add |
| 2977 | * @alen: length of @addr | 2977 | * @alen: length of @addr |
| 2978 | * | 2978 | * |
| 2979 | * Add a secondary unicast address to the device or increase | 2979 | * Add a secondary unicast address to the device or increase |
| @@ -4585,8 +4585,8 @@ static int __init net_dev_init(void) | |||
| 4585 | 4585 | ||
| 4586 | dev_boot_phase = 0; | 4586 | dev_boot_phase = 0; |
| 4587 | 4587 | ||
| 4588 | open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); | 4588 | open_softirq(NET_TX_SOFTIRQ, net_tx_action); |
| 4589 | open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); | 4589 | open_softirq(NET_RX_SOFTIRQ, net_rx_action); |
| 4590 | 4590 | ||
| 4591 | hotcpu_notifier(dev_cpu_callback, 0); | 4591 | hotcpu_notifier(dev_cpu_callback, 0); |
| 4592 | dst_init(); | 4592 | dst_init(); |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index e3e9ab0f74e3..277a2302eb3a 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
| @@ -226,7 +226,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 226 | 226 | ||
| 227 | ops = lookup_rules_ops(net, frh->family); | 227 | ops = lookup_rules_ops(net, frh->family); |
| 228 | if (ops == NULL) { | 228 | if (ops == NULL) { |
| 229 | err = EAFNOSUPPORT; | 229 | err = -EAFNOSUPPORT; |
| 230 | goto errout; | 230 | goto errout; |
| 231 | } | 231 | } |
| 232 | 232 | ||
| @@ -365,7 +365,7 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
| 365 | 365 | ||
| 366 | ops = lookup_rules_ops(net, frh->family); | 366 | ops = lookup_rules_ops(net, frh->family); |
| 367 | if (ops == NULL) { | 367 | if (ops == NULL) { |
| 368 | err = EAFNOSUPPORT; | 368 | err = -EAFNOSUPPORT; |
| 369 | goto errout; | 369 | goto errout; |
| 370 | } | 370 | } |
| 371 | 371 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index 4f8369729a4e..df3744355839 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -68,7 +68,6 @@ static inline void *load_pointer(struct sk_buff *skb, int k, | |||
| 68 | * sk_filter - run a packet through a socket filter | 68 | * sk_filter - run a packet through a socket filter |
| 69 | * @sk: sock associated with &sk_buff | 69 | * @sk: sock associated with &sk_buff |
| 70 | * @skb: buffer to filter | 70 | * @skb: buffer to filter |
| 71 | * @needlock: set to 1 if the sock is not locked by caller. | ||
| 72 | * | 71 | * |
| 73 | * Run the filter code and then cut skb->data to correct size returned by | 72 | * Run the filter code and then cut skb->data to correct size returned by |
| 74 | * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller | 73 | * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller |
diff --git a/net/core/flow.c b/net/core/flow.c index 19991175fdeb..5cf81052d044 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
| @@ -298,7 +298,7 @@ void flow_cache_flush(void) | |||
| 298 | init_completion(&info.completion); | 298 | init_completion(&info.completion); |
| 299 | 299 | ||
| 300 | local_bh_disable(); | 300 | local_bh_disable(); |
| 301 | smp_call_function(flow_cache_flush_per_cpu, &info, 1, 0); | 301 | smp_call_function(flow_cache_flush_per_cpu, &info, 0); |
| 302 | flow_cache_flush_tasklet((unsigned long)&info); | 302 | flow_cache_flush_tasklet((unsigned long)&info); |
| 303 | local_bh_enable(); | 303 | local_bh_enable(); |
| 304 | 304 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1e556d312117..366621610e76 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -1292,12 +1292,14 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, | |||
| 1292 | { | 1292 | { |
| 1293 | unsigned int nr_pages = spd->nr_pages; | 1293 | unsigned int nr_pages = spd->nr_pages; |
| 1294 | unsigned int poff, plen, len, toff, tlen; | 1294 | unsigned int poff, plen, len, toff, tlen; |
| 1295 | int headlen, seg; | 1295 | int headlen, seg, error = 0; |
| 1296 | 1296 | ||
| 1297 | toff = *offset; | 1297 | toff = *offset; |
| 1298 | tlen = *total_len; | 1298 | tlen = *total_len; |
| 1299 | if (!tlen) | 1299 | if (!tlen) { |
| 1300 | error = 1; | ||
| 1300 | goto err; | 1301 | goto err; |
| 1302 | } | ||
| 1301 | 1303 | ||
| 1302 | /* | 1304 | /* |
| 1303 | * if the offset is greater than the linear part, go directly to | 1305 | * if the offset is greater than the linear part, go directly to |
| @@ -1339,7 +1341,8 @@ static int __skb_splice_bits(struct sk_buff *skb, unsigned int *offset, | |||
| 1339 | * just jump directly to update and return, no point | 1341 | * just jump directly to update and return, no point |
| 1340 | * in going over fragments when the output is full. | 1342 | * in going over fragments when the output is full. |
| 1341 | */ | 1343 | */ |
| 1342 | if (spd_fill_page(spd, virt_to_page(p), plen, poff, skb)) | 1344 | error = spd_fill_page(spd, virt_to_page(p), plen, poff, skb); |
| 1345 | if (error) | ||
| 1343 | goto done; | 1346 | goto done; |
| 1344 | 1347 | ||
| 1345 | tlen -= plen; | 1348 | tlen -= plen; |
| @@ -1369,7 +1372,8 @@ map_frag: | |||
| 1369 | if (!plen) | 1372 | if (!plen) |
| 1370 | break; | 1373 | break; |
| 1371 | 1374 | ||
| 1372 | if (spd_fill_page(spd, f->page, plen, poff, skb)) | 1375 | error = spd_fill_page(spd, f->page, plen, poff, skb); |
| 1376 | if (error) | ||
| 1373 | break; | 1377 | break; |
| 1374 | 1378 | ||
| 1375 | tlen -= plen; | 1379 | tlen -= plen; |
| @@ -1382,7 +1386,10 @@ done: | |||
| 1382 | return 0; | 1386 | return 0; |
| 1383 | } | 1387 | } |
| 1384 | err: | 1388 | err: |
| 1385 | return 1; | 1389 | /* update the offset to reflect the linear part skip, if any */ |
| 1390 | if (!error) | ||
| 1391 | *offset = toff; | ||
| 1392 | return error; | ||
| 1386 | } | 1393 | } |
| 1387 | 1394 | ||
| 1388 | /* | 1395 | /* |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 4b02d14e7ab9..e1600ad8fb0e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
| @@ -1359,17 +1359,17 @@ static int check_leaf(struct trie *t, struct leaf *l, | |||
| 1359 | t->stats.semantic_match_miss++; | 1359 | t->stats.semantic_match_miss++; |
| 1360 | #endif | 1360 | #endif |
| 1361 | if (err <= 0) | 1361 | if (err <= 0) |
| 1362 | return plen; | 1362 | return err; |
| 1363 | } | 1363 | } |
| 1364 | 1364 | ||
| 1365 | return -1; | 1365 | return 1; |
| 1366 | } | 1366 | } |
| 1367 | 1367 | ||
| 1368 | static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, | 1368 | static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, |
| 1369 | struct fib_result *res) | 1369 | struct fib_result *res) |
| 1370 | { | 1370 | { |
| 1371 | struct trie *t = (struct trie *) tb->tb_data; | 1371 | struct trie *t = (struct trie *) tb->tb_data; |
| 1372 | int plen, ret = 0; | 1372 | int ret; |
| 1373 | struct node *n; | 1373 | struct node *n; |
| 1374 | struct tnode *pn; | 1374 | struct tnode *pn; |
| 1375 | int pos, bits; | 1375 | int pos, bits; |
| @@ -1393,10 +1393,7 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, | |||
| 1393 | 1393 | ||
| 1394 | /* Just a leaf? */ | 1394 | /* Just a leaf? */ |
| 1395 | if (IS_LEAF(n)) { | 1395 | if (IS_LEAF(n)) { |
| 1396 | plen = check_leaf(t, (struct leaf *)n, key, flp, res); | 1396 | ret = check_leaf(t, (struct leaf *)n, key, flp, res); |
| 1397 | if (plen < 0) | ||
| 1398 | goto failed; | ||
| 1399 | ret = 0; | ||
| 1400 | goto found; | 1397 | goto found; |
| 1401 | } | 1398 | } |
| 1402 | 1399 | ||
| @@ -1421,11 +1418,9 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, | |||
| 1421 | } | 1418 | } |
| 1422 | 1419 | ||
| 1423 | if (IS_LEAF(n)) { | 1420 | if (IS_LEAF(n)) { |
| 1424 | plen = check_leaf(t, (struct leaf *)n, key, flp, res); | 1421 | ret = check_leaf(t, (struct leaf *)n, key, flp, res); |
| 1425 | if (plen < 0) | 1422 | if (ret > 0) |
| 1426 | goto backtrace; | 1423 | goto backtrace; |
| 1427 | |||
| 1428 | ret = 0; | ||
| 1429 | goto found; | 1424 | goto found; |
| 1430 | } | 1425 | } |
| 1431 | 1426 | ||
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 4ed429bd5951..0546a0bc97ea 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
| @@ -192,14 +192,21 @@ EXPORT_SYMBOL(inet_frag_evictor); | |||
| 192 | 192 | ||
| 193 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, | 193 | static struct inet_frag_queue *inet_frag_intern(struct netns_frags *nf, |
| 194 | struct inet_frag_queue *qp_in, struct inet_frags *f, | 194 | struct inet_frag_queue *qp_in, struct inet_frags *f, |
| 195 | unsigned int hash, void *arg) | 195 | void *arg) |
| 196 | { | 196 | { |
| 197 | struct inet_frag_queue *qp; | 197 | struct inet_frag_queue *qp; |
| 198 | #ifdef CONFIG_SMP | 198 | #ifdef CONFIG_SMP |
| 199 | struct hlist_node *n; | 199 | struct hlist_node *n; |
| 200 | #endif | 200 | #endif |
| 201 | unsigned int hash; | ||
| 201 | 202 | ||
| 202 | write_lock(&f->lock); | 203 | write_lock(&f->lock); |
| 204 | /* | ||
| 205 | * While we stayed w/o the lock other CPU could update | ||
| 206 | * the rnd seed, so we need to re-calculate the hash | ||
| 207 | * chain. Fortunatelly the qp_in can be used to get one. | ||
| 208 | */ | ||
| 209 | hash = f->hashfn(qp_in); | ||
| 203 | #ifdef CONFIG_SMP | 210 | #ifdef CONFIG_SMP |
| 204 | /* With SMP race we have to recheck hash table, because | 211 | /* With SMP race we have to recheck hash table, because |
| 205 | * such entry could be created on other cpu, while we | 212 | * such entry could be created on other cpu, while we |
| @@ -247,7 +254,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, | |||
| 247 | } | 254 | } |
| 248 | 255 | ||
| 249 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, | 256 | static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, |
| 250 | struct inet_frags *f, void *arg, unsigned int hash) | 257 | struct inet_frags *f, void *arg) |
| 251 | { | 258 | { |
| 252 | struct inet_frag_queue *q; | 259 | struct inet_frag_queue *q; |
| 253 | 260 | ||
| @@ -255,7 +262,7 @@ static struct inet_frag_queue *inet_frag_create(struct netns_frags *nf, | |||
| 255 | if (q == NULL) | 262 | if (q == NULL) |
| 256 | return NULL; | 263 | return NULL; |
| 257 | 264 | ||
| 258 | return inet_frag_intern(nf, q, f, hash, arg); | 265 | return inet_frag_intern(nf, q, f, arg); |
| 259 | } | 266 | } |
| 260 | 267 | ||
| 261 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | 268 | struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, |
| @@ -264,7 +271,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | |||
| 264 | struct inet_frag_queue *q; | 271 | struct inet_frag_queue *q; |
| 265 | struct hlist_node *n; | 272 | struct hlist_node *n; |
| 266 | 273 | ||
| 267 | read_lock(&f->lock); | ||
| 268 | hlist_for_each_entry(q, n, &f->hash[hash], list) { | 274 | hlist_for_each_entry(q, n, &f->hash[hash], list) { |
| 269 | if (q->net == nf && f->match(q, key)) { | 275 | if (q->net == nf && f->match(q, key)) { |
| 270 | atomic_inc(&q->refcnt); | 276 | atomic_inc(&q->refcnt); |
| @@ -274,6 +280,6 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, | |||
| 274 | } | 280 | } |
| 275 | read_unlock(&f->lock); | 281 | read_unlock(&f->lock); |
| 276 | 282 | ||
| 277 | return inet_frag_create(nf, f, key, hash); | 283 | return inet_frag_create(nf, f, key); |
| 278 | } | 284 | } |
| 279 | EXPORT_SYMBOL(inet_frag_find); | 285 | EXPORT_SYMBOL(inet_frag_find); |
diff --git a/net/ipv4/inet_lro.c b/net/ipv4/inet_lro.c index 4a4d49fca1f2..cfd034a2b96e 100644 --- a/net/ipv4/inet_lro.c +++ b/net/ipv4/inet_lro.c | |||
| @@ -383,8 +383,7 @@ static int __lro_proc_skb(struct net_lro_mgr *lro_mgr, struct sk_buff *skb, | |||
| 383 | out2: /* send aggregated SKBs to stack */ | 383 | out2: /* send aggregated SKBs to stack */ |
| 384 | lro_flush(lro_mgr, lro_desc); | 384 | lro_flush(lro_mgr, lro_desc); |
| 385 | 385 | ||
| 386 | out: /* Original SKB has to be posted to stack */ | 386 | out: |
| 387 | skb->ip_summed = lro_mgr->ip_summed; | ||
| 388 | return 1; | 387 | return 1; |
| 389 | } | 388 | } |
| 390 | 389 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index cd6ce6ac6358..37221f659159 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -229,6 +229,8 @@ static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user) | |||
| 229 | 229 | ||
| 230 | arg.iph = iph; | 230 | arg.iph = iph; |
| 231 | arg.user = user; | 231 | arg.user = user; |
| 232 | |||
| 233 | read_lock(&ip4_frags.lock); | ||
| 232 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); | 234 | hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); |
| 233 | 235 | ||
| 234 | q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); | 236 | q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash); |
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index 7750c97fde7b..ffeaffc3fffe 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
| @@ -439,8 +439,8 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, | |||
| 439 | unsigned int *len) | 439 | unsigned int *len) |
| 440 | { | 440 | { |
| 441 | unsigned long subid; | 441 | unsigned long subid; |
| 442 | unsigned int size; | ||
| 443 | unsigned long *optr; | 442 | unsigned long *optr; |
| 443 | size_t size; | ||
| 444 | 444 | ||
| 445 | size = eoc - ctx->pointer + 1; | 445 | size = eoc - ctx->pointer + 1; |
| 446 | 446 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index fc54a48fde1e..1d723de18686 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -255,11 +255,14 @@ | |||
| 255 | #include <linux/init.h> | 255 | #include <linux/init.h> |
| 256 | #include <linux/fs.h> | 256 | #include <linux/fs.h> |
| 257 | #include <linux/skbuff.h> | 257 | #include <linux/skbuff.h> |
| 258 | #include <linux/scatterlist.h> | ||
| 258 | #include <linux/splice.h> | 259 | #include <linux/splice.h> |
| 259 | #include <linux/net.h> | 260 | #include <linux/net.h> |
| 260 | #include <linux/socket.h> | 261 | #include <linux/socket.h> |
| 261 | #include <linux/random.h> | 262 | #include <linux/random.h> |
| 262 | #include <linux/bootmem.h> | 263 | #include <linux/bootmem.h> |
| 264 | #include <linux/highmem.h> | ||
| 265 | #include <linux/swap.h> | ||
| 263 | #include <linux/cache.h> | 266 | #include <linux/cache.h> |
| 264 | #include <linux/err.h> | 267 | #include <linux/err.h> |
| 265 | #include <linux/crypto.h> | 268 | #include <linux/crypto.h> |
| @@ -1206,7 +1209,8 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
| 1206 | return -ENOTCONN; | 1209 | return -ENOTCONN; |
| 1207 | while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { | 1210 | while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { |
| 1208 | if (offset < skb->len) { | 1211 | if (offset < skb->len) { |
| 1209 | size_t used, len; | 1212 | int used; |
| 1213 | size_t len; | ||
| 1210 | 1214 | ||
| 1211 | len = skb->len - offset; | 1215 | len = skb->len - offset; |
| 1212 | /* Stop reading if we hit a patch of urgent data */ | 1216 | /* Stop reading if we hit a patch of urgent data */ |
| @@ -2620,7 +2624,7 @@ __setup("thash_entries=", set_thash_entries); | |||
| 2620 | void __init tcp_init(void) | 2624 | void __init tcp_init(void) |
| 2621 | { | 2625 | { |
| 2622 | struct sk_buff *skb = NULL; | 2626 | struct sk_buff *skb = NULL; |
| 2623 | unsigned long limit; | 2627 | unsigned long nr_pages, limit; |
| 2624 | int order, i, max_share; | 2628 | int order, i, max_share; |
| 2625 | 2629 | ||
| 2626 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); | 2630 | BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb)); |
| @@ -2689,8 +2693,9 @@ void __init tcp_init(void) | |||
| 2689 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | 2693 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of |
| 2690 | * memory, with a floor of 128 pages. | 2694 | * memory, with a floor of 128 pages. |
| 2691 | */ | 2695 | */ |
| 2692 | limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | 2696 | nr_pages = totalram_pages - totalhigh_pages; |
| 2693 | limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | 2697 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); |
| 2698 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
| 2694 | limit = max(limit, 128UL); | 2699 | limit = max(limit, 128UL); |
| 2695 | sysctl_tcp_mem[0] = limit / 4 * 3; | 2700 | sysctl_tcp_mem[0] = limit / 4 * 3; |
| 2696 | sysctl_tcp_mem[1] = limit; | 2701 | sysctl_tcp_mem[1] = limit; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 12695be2c255..ffe869ac1bcf 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -2291,7 +2291,7 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
| 2291 | } | 2291 | } |
| 2292 | 2292 | ||
| 2293 | seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " | 2293 | seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX " |
| 2294 | "%08X %5d %8d %lu %d %p %u %u %u %u %d%n", | 2294 | "%08X %5d %8d %lu %d %p %lu %lu %u %u %d%n", |
| 2295 | i, src, srcp, dest, destp, sk->sk_state, | 2295 | i, src, srcp, dest, destp, sk->sk_state, |
| 2296 | tp->write_seq - tp->snd_una, | 2296 | tp->write_seq - tp->snd_una, |
| 2297 | sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : | 2297 | sk->sk_state == TCP_LISTEN ? sk->sk_ack_backlog : |
| @@ -2303,8 +2303,8 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len) | |||
| 2303 | icsk->icsk_probes_out, | 2303 | icsk->icsk_probes_out, |
| 2304 | sock_i_ino(sk), | 2304 | sock_i_ino(sk), |
| 2305 | atomic_read(&sk->sk_refcnt), sk, | 2305 | atomic_read(&sk->sk_refcnt), sk, |
| 2306 | icsk->icsk_rto, | 2306 | jiffies_to_clock_t(icsk->icsk_rto), |
| 2307 | icsk->icsk_ack.ato, | 2307 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
| 2308 | (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, | 2308 | (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong, |
| 2309 | tp->snd_cwnd, | 2309 | tp->snd_cwnd, |
| 2310 | tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, | 2310 | tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh, |
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 5ff0ce6e9d39..7ddc30f0744f 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
| @@ -224,7 +224,7 @@ static __init int tcpprobe_init(void) | |||
| 224 | if (bufsize < 0) | 224 | if (bufsize < 0) |
| 225 | return -EINVAL; | 225 | return -EINVAL; |
| 226 | 226 | ||
| 227 | tcp_probe.log = kcalloc(sizeof(struct tcp_log), bufsize, GFP_KERNEL); | 227 | tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL); |
| 228 | if (!tcp_probe.log) | 228 | if (!tcp_probe.log) |
| 229 | goto err0; | 229 | goto err0; |
| 230 | 230 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 147588f4c7c0..ff61a5cdb0b3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -749,12 +749,12 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
| 749 | } | 749 | } |
| 750 | write_unlock_bh(&idev->lock); | 750 | write_unlock_bh(&idev->lock); |
| 751 | 751 | ||
| 752 | addrconf_del_timer(ifp); | ||
| 753 | |||
| 752 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 754 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
| 753 | 755 | ||
| 754 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); | 756 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); |
| 755 | 757 | ||
| 756 | addrconf_del_timer(ifp); | ||
| 757 | |||
| 758 | /* | 758 | /* |
| 759 | * Purge or update corresponding prefix | 759 | * Purge or update corresponding prefix |
| 760 | * | 760 | * |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 3cd1c993d52b..dcf94fdfb863 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
| @@ -445,7 +445,7 @@ looped_back: | |||
| 445 | kfree_skb(skb); | 445 | kfree_skb(skb); |
| 446 | return -1; | 446 | return -1; |
| 447 | } | 447 | } |
| 448 | if (!ipv6_chk_home_addr(&init_net, addr)) { | 448 | if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) { |
| 449 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), | 449 | IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), |
| 450 | IPSTATS_MIB_INADDRERRORS); | 450 | IPSTATS_MIB_INADDRERRORS); |
| 451 | kfree_skb(skb); | 451 | kfree_skb(skb); |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 27a5e8b48d93..f405cea21a8b 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
| @@ -129,7 +129,7 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = { | |||
| 129 | .priority = NF_IP6_PRI_MANGLE, | 129 | .priority = NF_IP6_PRI_MANGLE, |
| 130 | }, | 130 | }, |
| 131 | { | 131 | { |
| 132 | .hook = ip6t_local_hook, | 132 | .hook = ip6t_route_hook, |
| 133 | .owner = THIS_MODULE, | 133 | .owner = THIS_MODULE, |
| 134 | .pf = PF_INET6, | 134 | .pf = PF_INET6, |
| 135 | .hooknum = NF_INET_LOCAL_IN, | 135 | .hooknum = NF_INET_LOCAL_IN, |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index e65e26e210ee..cf20bc4fd60d 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -207,9 +207,10 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) | |||
| 207 | arg.id = id; | 207 | arg.id = id; |
| 208 | arg.src = src; | 208 | arg.src = src; |
| 209 | arg.dst = dst; | 209 | arg.dst = dst; |
| 210 | |||
| 211 | read_lock_bh(&nf_frags.lock); | ||
| 210 | hash = ip6qhashfn(id, src, dst); | 212 | hash = ip6qhashfn(id, src, dst); |
| 211 | 213 | ||
| 212 | local_bh_disable(); | ||
| 213 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); | 214 | q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); |
| 214 | local_bh_enable(); | 215 | local_bh_enable(); |
| 215 | if (q == NULL) | 216 | if (q == NULL) |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 798cabc7535b..a60d7d129713 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
| @@ -247,6 +247,8 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst, | |||
| 247 | arg.id = id; | 247 | arg.id = id; |
| 248 | arg.src = src; | 248 | arg.src = src; |
| 249 | arg.dst = dst; | 249 | arg.dst = dst; |
| 250 | |||
| 251 | read_lock(&ip6_frags.lock); | ||
| 250 | hash = ip6qhashfn(id, src, dst); | 252 | hash = ip6qhashfn(id, src, dst); |
| 251 | 253 | ||
| 252 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); | 254 | q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index d1f3e19b06c7..7ff687020fa9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -240,7 +240,7 @@ static inline int rt6_need_strict(struct in6_addr *daddr) | |||
| 240 | static inline struct rt6_info *rt6_device_match(struct net *net, | 240 | static inline struct rt6_info *rt6_device_match(struct net *net, |
| 241 | struct rt6_info *rt, | 241 | struct rt6_info *rt, |
| 242 | int oif, | 242 | int oif, |
| 243 | int strict) | 243 | int flags) |
| 244 | { | 244 | { |
| 245 | struct rt6_info *local = NULL; | 245 | struct rt6_info *local = NULL; |
| 246 | struct rt6_info *sprt; | 246 | struct rt6_info *sprt; |
| @@ -253,7 +253,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
| 253 | if (dev->flags & IFF_LOOPBACK) { | 253 | if (dev->flags & IFF_LOOPBACK) { |
| 254 | if (sprt->rt6i_idev == NULL || | 254 | if (sprt->rt6i_idev == NULL || |
| 255 | sprt->rt6i_idev->dev->ifindex != oif) { | 255 | sprt->rt6i_idev->dev->ifindex != oif) { |
| 256 | if (strict && oif) | 256 | if (flags & RT6_LOOKUP_F_IFACE && oif) |
| 257 | continue; | 257 | continue; |
| 258 | if (local && (!oif || | 258 | if (local && (!oif || |
| 259 | local->rt6i_idev->dev->ifindex == oif)) | 259 | local->rt6i_idev->dev->ifindex == oif)) |
| @@ -266,7 +266,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, | |||
| 266 | if (local) | 266 | if (local) |
| 267 | return local; | 267 | return local; |
| 268 | 268 | ||
| 269 | if (strict) | 269 | if (flags & RT6_LOOKUP_F_IFACE) |
| 270 | return net->ipv6.ip6_null_entry; | 270 | return net->ipv6.ip6_null_entry; |
| 271 | } | 271 | } |
| 272 | return rt; | 272 | return rt; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index cb46749d4c32..40ea9c36d24b 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -2036,7 +2036,7 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
| 2036 | 2036 | ||
| 2037 | seq_printf(seq, | 2037 | seq_printf(seq, |
| 2038 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " | 2038 | "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " |
| 2039 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", | 2039 | "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u %d\n", |
| 2040 | i, | 2040 | i, |
| 2041 | src->s6_addr32[0], src->s6_addr32[1], | 2041 | src->s6_addr32[0], src->s6_addr32[1], |
| 2042 | src->s6_addr32[2], src->s6_addr32[3], srcp, | 2042 | src->s6_addr32[2], src->s6_addr32[3], srcp, |
| @@ -2052,8 +2052,8 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) | |||
| 2052 | icsk->icsk_probes_out, | 2052 | icsk->icsk_probes_out, |
| 2053 | sock_i_ino(sp), | 2053 | sock_i_ino(sp), |
| 2054 | atomic_read(&sp->sk_refcnt), sp, | 2054 | atomic_read(&sp->sk_refcnt), sp, |
| 2055 | icsk->icsk_rto, | 2055 | jiffies_to_clock_t(icsk->icsk_rto), |
| 2056 | icsk->icsk_ack.ato, | 2056 | jiffies_to_clock_t(icsk->icsk_ack.ato), |
| 2057 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, | 2057 | (icsk->icsk_ack.quick << 1 ) | icsk->icsk_ack.pingpong, |
| 2058 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh | 2058 | tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh |
| 2059 | ); | 2059 | ); |
diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index b001c361ad30..bccf4d0059f0 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h | |||
| @@ -241,6 +241,7 @@ | |||
| 241 | #include <linux/module.h> | 241 | #include <linux/module.h> |
| 242 | 242 | ||
| 243 | #include <linux/kernel.h> | 243 | #include <linux/kernel.h> |
| 244 | #include <linux/smp_lock.h> | ||
| 244 | #include <linux/skbuff.h> | 245 | #include <linux/skbuff.h> |
| 245 | #include <linux/tty.h> | 246 | #include <linux/tty.h> |
| 246 | #include <linux/proc_fs.h> | 247 | #include <linux/proc_fs.h> |
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index e0eab5927c4f..e84a70dd346b 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c | |||
| @@ -479,6 +479,7 @@ dev_irnet_open(struct inode * inode, | |||
| 479 | ap = kzalloc(sizeof(*ap), GFP_KERNEL); | 479 | ap = kzalloc(sizeof(*ap), GFP_KERNEL); |
| 480 | DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); | 480 | DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); |
| 481 | 481 | ||
| 482 | lock_kernel(); | ||
| 482 | /* initialize the irnet structure */ | 483 | /* initialize the irnet structure */ |
| 483 | ap->file = file; | 484 | ap->file = file; |
| 484 | 485 | ||
| @@ -500,6 +501,7 @@ dev_irnet_open(struct inode * inode, | |||
| 500 | { | 501 | { |
| 501 | DERROR(FS_ERROR, "Can't setup IrDA link...\n"); | 502 | DERROR(FS_ERROR, "Can't setup IrDA link...\n"); |
| 502 | kfree(ap); | 503 | kfree(ap); |
| 504 | unlock_kernel(); | ||
| 503 | return err; | 505 | return err; |
| 504 | } | 506 | } |
| 505 | 507 | ||
| @@ -510,6 +512,7 @@ dev_irnet_open(struct inode * inode, | |||
| 510 | file->private_data = ap; | 512 | file->private_data = ap; |
| 511 | 513 | ||
| 512 | DEXIT(FS_TRACE, " - ap=0x%p\n", ap); | 514 | DEXIT(FS_TRACE, " - ap=0x%p\n", ap); |
| 515 | unlock_kernel(); | ||
| 513 | return 0; | 516 | return 0; |
| 514 | } | 517 | } |
| 515 | 518 | ||
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c index 9e1fb82e3220..2f05ec1037ab 100644 --- a/net/irda/irnetlink.c +++ b/net/irda/irnetlink.c | |||
| @@ -101,8 +101,8 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info) | |||
| 101 | 101 | ||
| 102 | hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, | 102 | hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq, |
| 103 | &irda_nl_family, 0, IRDA_NL_CMD_GET_MODE); | 103 | &irda_nl_family, 0, IRDA_NL_CMD_GET_MODE); |
| 104 | if (IS_ERR(hdr)) { | 104 | if (hdr == NULL) { |
| 105 | ret = PTR_ERR(hdr); | 105 | ret = -EMSGSIZE; |
| 106 | goto err_out; | 106 | goto err_out; |
| 107 | } | 107 | } |
| 108 | 108 | ||
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 7b0038f45b16..bda71015885c 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
| @@ -1135,8 +1135,7 @@ static void iucv_callback_txdone(struct iucv_path *path, | |||
| 1135 | if (this) | 1135 | if (this) |
| 1136 | kfree_skb(this); | 1136 | kfree_skb(this); |
| 1137 | } | 1137 | } |
| 1138 | if (!this) | 1138 | BUG_ON(!this); |
| 1139 | printk(KERN_ERR "AF_IUCV msg tag %u not found\n", msg->tag); | ||
| 1140 | 1139 | ||
| 1141 | if (sk->sk_state == IUCV_CLOSING) { | 1140 | if (sk->sk_state == IUCV_CLOSING) { |
| 1142 | if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) { | 1141 | if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) { |
| @@ -1196,7 +1195,7 @@ static int __init afiucv_init(void) | |||
| 1196 | } | 1195 | } |
| 1197 | cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err); | 1196 | cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err); |
| 1198 | if (unlikely(err)) { | 1197 | if (unlikely(err)) { |
| 1199 | printk(KERN_ERR "AF_IUCV needs the VM userid\n"); | 1198 | WARN_ON(err); |
| 1200 | err = -EPROTONOSUPPORT; | 1199 | err = -EPROTONOSUPPORT; |
| 1201 | goto out; | 1200 | goto out; |
| 1202 | } | 1201 | } |
| @@ -1210,7 +1209,6 @@ static int __init afiucv_init(void) | |||
| 1210 | err = sock_register(&iucv_sock_family_ops); | 1209 | err = sock_register(&iucv_sock_family_ops); |
| 1211 | if (err) | 1210 | if (err) |
| 1212 | goto out_proto; | 1211 | goto out_proto; |
| 1213 | printk(KERN_INFO "AF_IUCV lowlevel driver initialized\n"); | ||
| 1214 | return 0; | 1212 | return 0; |
| 1215 | 1213 | ||
| 1216 | out_proto: | 1214 | out_proto: |
| @@ -1226,8 +1224,6 @@ static void __exit afiucv_exit(void) | |||
| 1226 | sock_unregister(PF_IUCV); | 1224 | sock_unregister(PF_IUCV); |
| 1227 | proto_unregister(&iucv_proto); | 1225 | proto_unregister(&iucv_proto); |
| 1228 | iucv_unregister(&af_iucv_handler, 0); | 1226 | iucv_unregister(&af_iucv_handler, 0); |
| 1229 | |||
| 1230 | printk(KERN_INFO "AF_IUCV lowlevel driver unloaded\n"); | ||
| 1231 | } | 1227 | } |
| 1232 | 1228 | ||
| 1233 | module_init(afiucv_init); | 1229 | module_init(afiucv_init); |
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 918970762131..cc34ac769a3c 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c | |||
| @@ -480,7 +480,7 @@ static void iucv_setmask_mp(void) | |||
| 480 | if (cpu_isset(cpu, iucv_buffer_cpumask) && | 480 | if (cpu_isset(cpu, iucv_buffer_cpumask) && |
| 481 | !cpu_isset(cpu, iucv_irq_cpumask)) | 481 | !cpu_isset(cpu, iucv_irq_cpumask)) |
| 482 | smp_call_function_single(cpu, iucv_allow_cpu, | 482 | smp_call_function_single(cpu, iucv_allow_cpu, |
| 483 | NULL, 0, 1); | 483 | NULL, 1); |
| 484 | preempt_enable(); | 484 | preempt_enable(); |
| 485 | } | 485 | } |
| 486 | 486 | ||
| @@ -498,7 +498,7 @@ static void iucv_setmask_up(void) | |||
| 498 | cpumask = iucv_irq_cpumask; | 498 | cpumask = iucv_irq_cpumask; |
| 499 | cpu_clear(first_cpu(iucv_irq_cpumask), cpumask); | 499 | cpu_clear(first_cpu(iucv_irq_cpumask), cpumask); |
| 500 | for_each_cpu_mask(cpu, cpumask) | 500 | for_each_cpu_mask(cpu, cpumask) |
| 501 | smp_call_function_single(cpu, iucv_block_cpu, NULL, 0, 1); | 501 | smp_call_function_single(cpu, iucv_block_cpu, NULL, 1); |
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | /** | 504 | /** |
| @@ -523,7 +523,7 @@ static int iucv_enable(void) | |||
| 523 | rc = -EIO; | 523 | rc = -EIO; |
| 524 | preempt_disable(); | 524 | preempt_disable(); |
| 525 | for_each_online_cpu(cpu) | 525 | for_each_online_cpu(cpu) |
| 526 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1); | 526 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1); |
| 527 | preempt_enable(); | 527 | preempt_enable(); |
| 528 | if (cpus_empty(iucv_buffer_cpumask)) | 528 | if (cpus_empty(iucv_buffer_cpumask)) |
| 529 | /* No cpu could declare an iucv buffer. */ | 529 | /* No cpu could declare an iucv buffer. */ |
| @@ -545,7 +545,7 @@ out: | |||
| 545 | */ | 545 | */ |
| 546 | static void iucv_disable(void) | 546 | static void iucv_disable(void) |
| 547 | { | 547 | { |
| 548 | on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1); | 548 | on_each_cpu(iucv_retrieve_cpu, NULL, 1); |
| 549 | kfree(iucv_path_table); | 549 | kfree(iucv_path_table); |
| 550 | } | 550 | } |
| 551 | 551 | ||
| @@ -580,7 +580,7 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
| 580 | case CPU_ONLINE_FROZEN: | 580 | case CPU_ONLINE_FROZEN: |
| 581 | case CPU_DOWN_FAILED: | 581 | case CPU_DOWN_FAILED: |
| 582 | case CPU_DOWN_FAILED_FROZEN: | 582 | case CPU_DOWN_FAILED_FROZEN: |
| 583 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1); | 583 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1); |
| 584 | break; | 584 | break; |
| 585 | case CPU_DOWN_PREPARE: | 585 | case CPU_DOWN_PREPARE: |
| 586 | case CPU_DOWN_PREPARE_FROZEN: | 586 | case CPU_DOWN_PREPARE_FROZEN: |
| @@ -589,10 +589,10 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
| 589 | if (cpus_empty(cpumask)) | 589 | if (cpus_empty(cpumask)) |
| 590 | /* Can't offline last IUCV enabled cpu. */ | 590 | /* Can't offline last IUCV enabled cpu. */ |
| 591 | return NOTIFY_BAD; | 591 | return NOTIFY_BAD; |
| 592 | smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 0, 1); | 592 | smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 1); |
| 593 | if (cpus_empty(iucv_irq_cpumask)) | 593 | if (cpus_empty(iucv_irq_cpumask)) |
| 594 | smp_call_function_single(first_cpu(iucv_buffer_cpumask), | 594 | smp_call_function_single(first_cpu(iucv_buffer_cpumask), |
| 595 | iucv_allow_cpu, NULL, 0, 1); | 595 | iucv_allow_cpu, NULL, 1); |
| 596 | break; | 596 | break; |
| 597 | } | 597 | } |
| 598 | return NOTIFY_OK; | 598 | return NOTIFY_OK; |
| @@ -652,7 +652,7 @@ static void iucv_cleanup_queue(void) | |||
| 652 | * pending interrupts force them to the work queue by calling | 652 | * pending interrupts force them to the work queue by calling |
| 653 | * an empty function on all cpus. | 653 | * an empty function on all cpus. |
| 654 | */ | 654 | */ |
| 655 | smp_call_function(__iucv_cleanup_queue, NULL, 0, 1); | 655 | smp_call_function(__iucv_cleanup_queue, NULL, 1); |
| 656 | spin_lock_irq(&iucv_queue_lock); | 656 | spin_lock_irq(&iucv_queue_lock); |
| 657 | list_for_each_entry_safe(p, n, &iucv_task_queue, list) { | 657 | list_for_each_entry_safe(p, n, &iucv_task_queue, list) { |
| 658 | /* Remove stale work items from the task queue. */ | 658 | /* Remove stale work items from the task queue. */ |
| @@ -1559,16 +1559,11 @@ static void iucv_external_interrupt(u16 code) | |||
| 1559 | 1559 | ||
| 1560 | p = iucv_irq_data[smp_processor_id()]; | 1560 | p = iucv_irq_data[smp_processor_id()]; |
| 1561 | if (p->ippathid >= iucv_max_pathid) { | 1561 | if (p->ippathid >= iucv_max_pathid) { |
| 1562 | printk(KERN_WARNING "iucv_do_int: Got interrupt with " | 1562 | WARN_ON(p->ippathid >= iucv_max_pathid); |
| 1563 | "pathid %d > max_connections (%ld)\n", | ||
| 1564 | p->ippathid, iucv_max_pathid - 1); | ||
| 1565 | iucv_sever_pathid(p->ippathid, iucv_error_no_listener); | 1563 | iucv_sever_pathid(p->ippathid, iucv_error_no_listener); |
| 1566 | return; | 1564 | return; |
| 1567 | } | 1565 | } |
| 1568 | if (p->iptype < 0x01 || p->iptype > 0x09) { | 1566 | BUG_ON(p->iptype < 0x01 || p->iptype > 0x09); |
| 1569 | printk(KERN_ERR "iucv_do_int: unknown iucv interrupt\n"); | ||
| 1570 | return; | ||
| 1571 | } | ||
| 1572 | work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); | 1567 | work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); |
| 1573 | if (!work) { | 1568 | if (!work) { |
| 1574 | printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); | 1569 | printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 150d66dbda9d..220e83be3ef4 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
| @@ -380,6 +380,15 @@ void ieee80211_key_free(struct ieee80211_key *key) | |||
| 380 | if (!key) | 380 | if (!key) |
| 381 | return; | 381 | return; |
| 382 | 382 | ||
| 383 | if (!key->sdata) { | ||
| 384 | /* The key has not been linked yet, simply free it | ||
| 385 | * and don't Oops */ | ||
| 386 | if (key->conf.alg == ALG_CCMP) | ||
| 387 | ieee80211_aes_key_free(key->u.ccmp.tfm); | ||
| 388 | kfree(key); | ||
| 389 | return; | ||
| 390 | } | ||
| 391 | |||
| 383 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); | 392 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); |
| 384 | __ieee80211_key_free(key); | 393 | __ieee80211_key_free(key); |
| 385 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); | 394 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 98c0b5e56ecc..df0836ff1a20 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -530,8 +530,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 530 | local->sta_hw_scanning = 0; | 530 | local->sta_hw_scanning = 0; |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | flush_workqueue(local->hw.workqueue); | ||
| 534 | |||
| 535 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | 533 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; |
| 536 | kfree(sdata->u.sta.extra_ie); | 534 | kfree(sdata->u.sta.extra_ie); |
| 537 | sdata->u.sta.extra_ie = NULL; | 535 | sdata->u.sta.extra_ie = NULL; |
| @@ -555,6 +553,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 555 | 553 | ||
| 556 | ieee80211_led_radio(local, 0); | 554 | ieee80211_led_radio(local, 0); |
| 557 | 555 | ||
| 556 | flush_workqueue(local->hw.workqueue); | ||
| 557 | |||
| 558 | tasklet_disable(&local->tx_pending_tasklet); | 558 | tasklet_disable(&local->tx_pending_tasklet); |
| 559 | tasklet_disable(&local->tasklet); | 559 | tasklet_disable(&local->tasklet); |
| 560 | } | 560 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4d2b582dd055..b404537c0bcd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -547,15 +547,14 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
| 547 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; | 547 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; |
| 548 | } | 548 | } |
| 549 | 549 | ||
| 550 | netif_carrier_on(dev); | ||
| 551 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; | 550 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; |
| 552 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 551 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
| 553 | memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); | 552 | memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); |
| 554 | ieee80211_sta_send_associnfo(dev, ifsta); | 553 | ieee80211_sta_send_associnfo(dev, ifsta); |
| 555 | } else { | 554 | } else { |
| 555 | netif_carrier_off(dev); | ||
| 556 | ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); | 556 | ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); |
| 557 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 557 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
| 558 | netif_carrier_off(dev); | ||
| 559 | ieee80211_reset_erp_info(dev); | 558 | ieee80211_reset_erp_info(dev); |
| 560 | 559 | ||
| 561 | sdata->bss_conf.assoc_ht = 0; | 560 | sdata->bss_conf.assoc_ht = 0; |
| @@ -569,6 +568,10 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
| 569 | 568 | ||
| 570 | sdata->bss_conf.assoc = assoc; | 569 | sdata->bss_conf.assoc = assoc; |
| 571 | ieee80211_bss_info_change_notify(sdata, changed); | 570 | ieee80211_bss_info_change_notify(sdata, changed); |
| 571 | |||
| 572 | if (assoc) | ||
| 573 | netif_carrier_on(dev); | ||
| 574 | |||
| 572 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 575 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
| 573 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 576 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); |
| 574 | } | 577 | } |
| @@ -3611,8 +3614,10 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
| 3611 | spin_unlock_bh(&local->sta_bss_lock); | 3614 | spin_unlock_bh(&local->sta_bss_lock); |
| 3612 | 3615 | ||
| 3613 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3616 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 3614 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " | 3617 | if (found) |
| 3615 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); | 3618 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " |
| 3619 | "%s\n", print_mac(mac, bssid), | ||
| 3620 | print_mac(mac2, ifsta->bssid)); | ||
| 3616 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 3621 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
| 3617 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && | 3622 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && |
| 3618 | (bss = ieee80211_rx_bss_get(dev, bssid, | 3623 | (bss = ieee80211_rx_bss_get(dev, bssid, |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 04afc13ed825..4ea7b97d1af1 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
| @@ -141,7 +141,6 @@ struct rc_pid_events_file_info { | |||
| 141 | * rate behaviour values (lower means we should trust more what we learnt | 141 | * rate behaviour values (lower means we should trust more what we learnt |
| 142 | * about behaviour of rates, higher means we should trust more the natural | 142 | * about behaviour of rates, higher means we should trust more the natural |
| 143 | * ordering of rates) | 143 | * ordering of rates) |
| 144 | * @fast_start: if Y, push high rates right after initialization | ||
| 145 | */ | 144 | */ |
| 146 | struct rc_pid_debugfs_entries { | 145 | struct rc_pid_debugfs_entries { |
| 147 | struct dentry *dir; | 146 | struct dentry *dir; |
| @@ -154,7 +153,6 @@ struct rc_pid_debugfs_entries { | |||
| 154 | struct dentry *sharpen_factor; | 153 | struct dentry *sharpen_factor; |
| 155 | struct dentry *sharpen_duration; | 154 | struct dentry *sharpen_duration; |
| 156 | struct dentry *norm_offset; | 155 | struct dentry *norm_offset; |
| 157 | struct dentry *fast_start; | ||
| 158 | }; | 156 | }; |
| 159 | 157 | ||
| 160 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | 158 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, |
| @@ -267,9 +265,6 @@ struct rc_pid_info { | |||
| 267 | /* Normalization offset. */ | 265 | /* Normalization offset. */ |
| 268 | unsigned int norm_offset; | 266 | unsigned int norm_offset; |
| 269 | 267 | ||
| 270 | /* Fast starst parameter. */ | ||
| 271 | unsigned int fast_start; | ||
| 272 | |||
| 273 | /* Rates information. */ | 268 | /* Rates information. */ |
| 274 | struct rc_pid_rateinfo *rinfo; | 269 | struct rc_pid_rateinfo *rinfo; |
| 275 | 270 | ||
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index a849b745bdb5..bcd27c1d7594 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
| @@ -398,13 +398,25 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
| 398 | return NULL; | 398 | return NULL; |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | pinfo->target = RC_PID_TARGET_PF; | ||
| 402 | pinfo->sampling_period = RC_PID_INTERVAL; | ||
| 403 | pinfo->coeff_p = RC_PID_COEFF_P; | ||
| 404 | pinfo->coeff_i = RC_PID_COEFF_I; | ||
| 405 | pinfo->coeff_d = RC_PID_COEFF_D; | ||
| 406 | pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT; | ||
| 407 | pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR; | ||
| 408 | pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION; | ||
| 409 | pinfo->norm_offset = RC_PID_NORM_OFFSET; | ||
| 410 | pinfo->rinfo = rinfo; | ||
| 411 | pinfo->oldrate = 0; | ||
| 412 | |||
| 401 | /* Sort the rates. This is optimized for the most common case (i.e. | 413 | /* Sort the rates. This is optimized for the most common case (i.e. |
| 402 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | 414 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed |
| 403 | * mapping too. */ | 415 | * mapping too. */ |
| 404 | for (i = 0; i < sband->n_bitrates; i++) { | 416 | for (i = 0; i < sband->n_bitrates; i++) { |
| 405 | rinfo[i].index = i; | 417 | rinfo[i].index = i; |
| 406 | rinfo[i].rev_index = i; | 418 | rinfo[i].rev_index = i; |
| 407 | if (pinfo->fast_start) | 419 | if (RC_PID_FAST_START) |
| 408 | rinfo[i].diff = 0; | 420 | rinfo[i].diff = 0; |
| 409 | else | 421 | else |
| 410 | rinfo[i].diff = i * pinfo->norm_offset; | 422 | rinfo[i].diff = i * pinfo->norm_offset; |
| @@ -425,19 +437,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
| 425 | break; | 437 | break; |
| 426 | } | 438 | } |
| 427 | 439 | ||
| 428 | pinfo->target = RC_PID_TARGET_PF; | ||
| 429 | pinfo->sampling_period = RC_PID_INTERVAL; | ||
| 430 | pinfo->coeff_p = RC_PID_COEFF_P; | ||
| 431 | pinfo->coeff_i = RC_PID_COEFF_I; | ||
| 432 | pinfo->coeff_d = RC_PID_COEFF_D; | ||
| 433 | pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT; | ||
| 434 | pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR; | ||
| 435 | pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION; | ||
| 436 | pinfo->norm_offset = RC_PID_NORM_OFFSET; | ||
| 437 | pinfo->fast_start = RC_PID_FAST_START; | ||
| 438 | pinfo->rinfo = rinfo; | ||
| 439 | pinfo->oldrate = 0; | ||
| 440 | |||
| 441 | #ifdef CONFIG_MAC80211_DEBUGFS | 440 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 442 | de = &pinfo->dentries; | 441 | de = &pinfo->dentries; |
| 443 | de->dir = debugfs_create_dir("rc80211_pid", | 442 | de->dir = debugfs_create_dir("rc80211_pid", |
| @@ -465,9 +464,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
| 465 | de->norm_offset = debugfs_create_u32("norm_offset", | 464 | de->norm_offset = debugfs_create_u32("norm_offset", |
| 466 | S_IRUSR | S_IWUSR, de->dir, | 465 | S_IRUSR | S_IWUSR, de->dir, |
| 467 | &pinfo->norm_offset); | 466 | &pinfo->norm_offset); |
| 468 | de->fast_start = debugfs_create_bool("fast_start", | ||
| 469 | S_IRUSR | S_IWUSR, de->dir, | ||
| 470 | &pinfo->fast_start); | ||
| 471 | #endif | 467 | #endif |
| 472 | 468 | ||
| 473 | return pinfo; | 469 | return pinfo; |
| @@ -479,7 +475,6 @@ static void rate_control_pid_free(void *priv) | |||
| 479 | #ifdef CONFIG_MAC80211_DEBUGFS | 475 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 480 | struct rc_pid_debugfs_entries *de = &pinfo->dentries; | 476 | struct rc_pid_debugfs_entries *de = &pinfo->dentries; |
| 481 | 477 | ||
| 482 | debugfs_remove(de->fast_start); | ||
| 483 | debugfs_remove(de->norm_offset); | 478 | debugfs_remove(de->norm_offset); |
| 484 | debugfs_remove(de->sharpen_duration); | 479 | debugfs_remove(de->sharpen_duration); |
| 485 | debugfs_remove(de->sharpen_factor); | 480 | debugfs_remove(de->sharpen_factor); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 6106cb79060c..e8404212ad57 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
| @@ -95,6 +95,13 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | if (alg == ALG_WEP && | ||
| 99 | key_len != LEN_WEP40 && key_len != LEN_WEP104) { | ||
| 100 | ieee80211_key_free(key); | ||
| 101 | err = -EINVAL; | ||
| 102 | goto out_unlock; | ||
| 103 | } | ||
| 104 | |||
| 98 | ieee80211_key_link(key, sdata, sta); | 105 | ieee80211_key_link(key, sdata, sta); |
| 99 | 106 | ||
| 100 | if (set_tx_key || (!sta && !sdata->default_key && key)) | 107 | if (set_tx_key || (!sta && !sdata->default_key && key)) |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 635b996c8c35..5d09e8698b57 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -323,8 +323,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd) | |||
| 323 | struct ieee80211_hw *hw = &local->hw; | 323 | struct ieee80211_hw *hw = &local->hw; |
| 324 | int queue; | 324 | int queue; |
| 325 | 325 | ||
| 326 | tcf_destroy_chain(q->filter_list); | 326 | tcf_destroy_chain(&q->filter_list); |
| 327 | q->filter_list = NULL; | ||
| 328 | 327 | ||
| 329 | for (queue=0; queue < hw->queues; queue++) { | 328 | for (queue=0; queue < hw->queues; queue++) { |
| 330 | skb_queue_purge(&q->requeued[queue]); | 329 | skb_queue_purge(&q->requeued[queue]); |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 7d1b11703741..8e0b4c8f62a8 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
| 23 | #include <linux/rculist.h> | ||
| 23 | 24 | ||
| 24 | #include <net/netfilter/nf_conntrack.h> | 25 | #include <net/netfilter/nf_conntrack.h> |
| 25 | #include <net/netfilter/nf_conntrack_l3proto.h> | 26 | #include <net/netfilter/nf_conntrack_l3proto.h> |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 0edefcfc5949..077bcd228799 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/rculist.h> | ||
| 21 | #include <linux/types.h> | 22 | #include <linux/types.h> |
| 22 | #include <linux/timer.h> | 23 | #include <linux/timer.h> |
| 23 | #include <linux/skbuff.h> | 24 | #include <linux/skbuff.h> |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index ba94004fe323..dd28fb239a60 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
| @@ -331,12 +331,13 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph) | |||
| 331 | 331 | ||
| 332 | I. Upper bound for valid data: seq <= sender.td_maxend | 332 | I. Upper bound for valid data: seq <= sender.td_maxend |
| 333 | II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin | 333 | II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin |
| 334 | III. Upper bound for valid ack: sack <= receiver.td_end | 334 | III. Upper bound for valid (s)ack: sack <= receiver.td_end |
| 335 | IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW | 335 | IV. Lower bound for valid (s)ack: sack >= receiver.td_end - MAXACKWINDOW |
| 336 | 336 | ||
| 337 | where sack is the highest right edge of sack block found in the packet. | 337 | where sack is the highest right edge of sack block found in the packet |
| 338 | or ack in the case of packet without SACK option. | ||
| 338 | 339 | ||
| 339 | The upper bound limit for a valid ack is not ignored - | 340 | The upper bound limit for a valid (s)ack is not ignored - |
| 340 | we doesn't have to deal with fragments. | 341 | we doesn't have to deal with fragments. |
| 341 | */ | 342 | */ |
| 342 | 343 | ||
| @@ -606,12 +607,12 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
| 606 | before(seq, sender->td_maxend + 1), | 607 | before(seq, sender->td_maxend + 1), |
| 607 | after(end, sender->td_end - receiver->td_maxwin - 1), | 608 | after(end, sender->td_end - receiver->td_maxwin - 1), |
| 608 | before(sack, receiver->td_end + 1), | 609 | before(sack, receiver->td_end + 1), |
| 609 | after(ack, receiver->td_end - MAXACKWINDOW(sender))); | 610 | after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)); |
| 610 | 611 | ||
| 611 | if (before(seq, sender->td_maxend + 1) && | 612 | if (before(seq, sender->td_maxend + 1) && |
| 612 | after(end, sender->td_end - receiver->td_maxwin - 1) && | 613 | after(end, sender->td_end - receiver->td_maxwin - 1) && |
| 613 | before(sack, receiver->td_end + 1) && | 614 | before(sack, receiver->td_end + 1) && |
| 614 | after(ack, receiver->td_end - MAXACKWINDOW(sender))) { | 615 | after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) { |
| 615 | /* | 616 | /* |
| 616 | * Take into account window scaling (RFC 1323). | 617 | * Take into account window scaling (RFC 1323). |
| 617 | */ | 618 | */ |
| @@ -843,9 +844,15 @@ static int tcp_packet(struct nf_conn *ct, | |||
| 843 | /* Attempt to reopen a closed/aborted connection. | 844 | /* Attempt to reopen a closed/aborted connection. |
| 844 | * Delete this connection and look up again. */ | 845 | * Delete this connection and look up again. */ |
| 845 | write_unlock_bh(&tcp_lock); | 846 | write_unlock_bh(&tcp_lock); |
| 846 | if (del_timer(&ct->timeout)) | 847 | /* Only repeat if we can actually remove the timer. |
| 848 | * Destruction may already be in progress in process | ||
| 849 | * context and we must give it a chance to terminate. | ||
| 850 | */ | ||
| 851 | if (del_timer(&ct->timeout)) { | ||
| 847 | ct->timeout.function((unsigned long)ct); | 852 | ct->timeout.function((unsigned long)ct); |
| 848 | return -NF_REPEAT; | 853 | return -NF_REPEAT; |
| 854 | } | ||
| 855 | return -NF_DROP; | ||
| 849 | } | 856 | } |
| 850 | /* Fall through */ | 857 | /* Fall through */ |
| 851 | case TCP_CONNTRACK_IGNORE: | 858 | case TCP_CONNTRACK_IGNORE: |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index fdc14a0d21af..9080c61b71a5 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
| @@ -584,12 +584,7 @@ list_start: | |||
| 584 | rcu_read_unlock(); | 584 | rcu_read_unlock(); |
| 585 | 585 | ||
| 586 | genlmsg_end(ans_skb, data); | 586 | genlmsg_end(ans_skb, data); |
| 587 | 587 | return genlmsg_reply(ans_skb, info); | |
| 588 | ret_val = genlmsg_reply(ans_skb, info); | ||
| 589 | if (ret_val != 0) | ||
| 590 | goto list_failure; | ||
| 591 | |||
| 592 | return 0; | ||
| 593 | 588 | ||
| 594 | list_retry: | 589 | list_retry: |
| 595 | /* XXX - this limit is a guesstimate */ | 590 | /* XXX - this limit is a guesstimate */ |
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 02c2f7c0b255..643c032a3a57 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
| @@ -30,8 +30,7 @@ | |||
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
| 33 | #include <linux/rcupdate.h> | 33 | #include <linux/rculist.h> |
| 34 | #include <linux/list.h> | ||
| 35 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
| 36 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
| 37 | #include <linux/string.h> | 36 | #include <linux/string.h> |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 22c191267808..44be5d5261f4 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
| @@ -386,11 +386,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info) | |||
| 386 | rcu_read_unlock(); | 386 | rcu_read_unlock(); |
| 387 | 387 | ||
| 388 | genlmsg_end(ans_skb, data); | 388 | genlmsg_end(ans_skb, data); |
| 389 | 389 | return genlmsg_reply(ans_skb, info); | |
| 390 | ret_val = genlmsg_reply(ans_skb, info); | ||
| 391 | if (ret_val != 0) | ||
| 392 | goto listdef_failure; | ||
| 393 | return 0; | ||
| 394 | 390 | ||
| 395 | listdef_failure_lock: | 391 | listdef_failure_lock: |
| 396 | rcu_read_unlock(); | 392 | rcu_read_unlock(); |
| @@ -501,11 +497,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info) | |||
| 501 | goto version_failure; | 497 | goto version_failure; |
| 502 | 498 | ||
| 503 | genlmsg_end(ans_skb, data); | 499 | genlmsg_end(ans_skb, data); |
| 504 | 500 | return genlmsg_reply(ans_skb, info); | |
| 505 | ret_val = genlmsg_reply(ans_skb, info); | ||
| 506 | if (ret_val != 0) | ||
| 507 | goto version_failure; | ||
| 508 | return 0; | ||
| 509 | 501 | ||
| 510 | version_failure: | 502 | version_failure: |
| 511 | kfree_skb(ans_skb); | 503 | kfree_skb(ans_skb); |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 0099da5b2591..56f80872924e 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
| @@ -1107,11 +1107,7 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info) | |||
| 1107 | goto list_failure; | 1107 | goto list_failure; |
| 1108 | 1108 | ||
| 1109 | genlmsg_end(ans_skb, data); | 1109 | genlmsg_end(ans_skb, data); |
| 1110 | 1110 | return genlmsg_reply(ans_skb, info); | |
| 1111 | ret_val = genlmsg_reply(ans_skb, info); | ||
| 1112 | if (ret_val != 0) | ||
| 1113 | goto list_failure; | ||
| 1114 | return 0; | ||
| 1115 | 1111 | ||
| 1116 | list_failure: | 1112 | list_failure: |
| 1117 | kfree_skb(ans_skb); | 1113 | kfree_skb(ans_skb); |
| @@ -1534,7 +1530,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb, | |||
| 1534 | } | 1530 | } |
| 1535 | } | 1531 | } |
| 1536 | list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { | 1532 | list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { |
| 1537 | if (addr6->valid || iter_addr6++ < skip_addr6) | 1533 | if (!addr6->valid || iter_addr6++ < skip_addr6) |
| 1538 | continue; | 1534 | continue; |
| 1539 | if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, | 1535 | if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, |
| 1540 | iface, | 1536 | iface, |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 9b97f8006c9c..349aba189558 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -886,7 +886,7 @@ retry: | |||
| 886 | return netlink_unicast_kernel(sk, skb); | 886 | return netlink_unicast_kernel(sk, skb); |
| 887 | 887 | ||
| 888 | if (sk_filter(sk, skb)) { | 888 | if (sk_filter(sk, skb)) { |
| 889 | int err = skb->len; | 889 | err = skb->len; |
| 890 | kfree_skb(skb); | 890 | kfree_skb(skb); |
| 891 | sock_put(sk); | 891 | sock_put(sk); |
| 892 | return err; | 892 | return err; |
diff --git a/net/netlink/attr.c b/net/netlink/attr.c index 47bbf45ae5d7..2d106cfe1d27 100644 --- a/net/netlink/attr.c +++ b/net/netlink/attr.c | |||
| @@ -132,6 +132,7 @@ errout: | |||
| 132 | * @maxtype: maximum attribute type to be expected | 132 | * @maxtype: maximum attribute type to be expected |
| 133 | * @head: head of attribute stream | 133 | * @head: head of attribute stream |
| 134 | * @len: length of attribute stream | 134 | * @len: length of attribute stream |
| 135 | * @policy: validation policy | ||
| 135 | * | 136 | * |
| 136 | * Parses a stream of attributes and stores a pointer to each attribute in | 137 | * Parses a stream of attributes and stores a pointer to each attribute in |
| 137 | * the tb array accessable via the attribute type. Attributes with a type | 138 | * the tb array accessable via the attribute type. Attributes with a type |
| @@ -194,7 +195,7 @@ struct nlattr *nla_find(struct nlattr *head, int len, int attrtype) | |||
| 194 | /** | 195 | /** |
| 195 | * nla_strlcpy - Copy string attribute payload into a sized buffer | 196 | * nla_strlcpy - Copy string attribute payload into a sized buffer |
| 196 | * @dst: where to copy the string to | 197 | * @dst: where to copy the string to |
| 197 | * @src: attribute to copy the string from | 198 | * @nla: attribute to copy the string from |
| 198 | * @dstsize: size of destination buffer | 199 | * @dstsize: size of destination buffer |
| 199 | * | 200 | * |
| 200 | * Copies at most dstsize - 1 bytes into the destination buffer. | 201 | * Copies at most dstsize - 1 bytes into the destination buffer. |
| @@ -340,9 +341,9 @@ struct nlattr *nla_reserve(struct sk_buff *skb, int attrtype, int attrlen) | |||
| 340 | } | 341 | } |
| 341 | 342 | ||
| 342 | /** | 343 | /** |
| 343 | * nla_reserve - reserve room for attribute without header | 344 | * nla_reserve_nohdr - reserve room for attribute without header |
| 344 | * @skb: socket buffer to reserve room on | 345 | * @skb: socket buffer to reserve room on |
| 345 | * @len: length of attribute payload | 346 | * @attrlen: length of attribute payload |
| 346 | * | 347 | * |
| 347 | * Reserves room for attribute payload without a header. | 348 | * Reserves room for attribute payload without a header. |
| 348 | * | 349 | * |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 82adfe6447d7..9437b27ff84d 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
| @@ -106,17 +106,6 @@ config NET_SCH_PRIO | |||
| 106 | To compile this code as a module, choose M here: the | 106 | To compile this code as a module, choose M here: the |
| 107 | module will be called sch_prio. | 107 | module will be called sch_prio. |
| 108 | 108 | ||
| 109 | config NET_SCH_RR | ||
| 110 | tristate "Multi Band Round Robin Queuing (RR)" | ||
| 111 | select NET_SCH_PRIO | ||
| 112 | ---help--- | ||
| 113 | Say Y here if you want to use an n-band round robin packet | ||
| 114 | scheduler. | ||
| 115 | |||
| 116 | The module uses sch_prio for its framework and is aliased as | ||
| 117 | sch_rr, so it will load sch_prio, although it is referred | ||
| 118 | to using sch_rr. | ||
| 119 | |||
| 120 | config NET_SCH_RED | 109 | config NET_SCH_RED |
| 121 | tristate "Random Early Detection (RED)" | 110 | tristate "Random Early Detection (RED)" |
| 122 | ---help--- | 111 | ---help--- |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index c40773cdbe45..10f01ad04380 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
| @@ -1252,12 +1252,12 @@ void tcf_destroy(struct tcf_proto *tp) | |||
| 1252 | kfree(tp); | 1252 | kfree(tp); |
| 1253 | } | 1253 | } |
| 1254 | 1254 | ||
| 1255 | void tcf_destroy_chain(struct tcf_proto *fl) | 1255 | void tcf_destroy_chain(struct tcf_proto **fl) |
| 1256 | { | 1256 | { |
| 1257 | struct tcf_proto *tp; | 1257 | struct tcf_proto *tp; |
| 1258 | 1258 | ||
| 1259 | while ((tp = fl) != NULL) { | 1259 | while ((tp = *fl) != NULL) { |
| 1260 | fl = tp->next; | 1260 | *fl = tp->next; |
| 1261 | tcf_destroy(tp); | 1261 | tcf_destroy(tp); |
| 1262 | } | 1262 | } |
| 1263 | } | 1263 | } |
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 335273416384..db0e23ae85f8 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c | |||
| @@ -160,7 +160,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl) | |||
| 160 | *prev = flow->next; | 160 | *prev = flow->next; |
| 161 | pr_debug("atm_tc_put: qdisc %p\n", flow->q); | 161 | pr_debug("atm_tc_put: qdisc %p\n", flow->q); |
| 162 | qdisc_destroy(flow->q); | 162 | qdisc_destroy(flow->q); |
| 163 | tcf_destroy_chain(flow->filter_list); | 163 | tcf_destroy_chain(&flow->filter_list); |
| 164 | if (flow->sock) { | 164 | if (flow->sock) { |
| 165 | pr_debug("atm_tc_put: f_count %d\n", | 165 | pr_debug("atm_tc_put: f_count %d\n", |
| 166 | file_count(flow->sock->file)); | 166 | file_count(flow->sock->file)); |
| @@ -586,10 +586,11 @@ static void atm_tc_destroy(struct Qdisc *sch) | |||
| 586 | struct atm_flow_data *flow; | 586 | struct atm_flow_data *flow; |
| 587 | 587 | ||
| 588 | pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p); | 588 | pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p); |
| 589 | for (flow = p->flows; flow; flow = flow->next) | ||
| 590 | tcf_destroy_chain(&flow->filter_list); | ||
| 591 | |||
| 589 | /* races ? */ | 592 | /* races ? */ |
| 590 | while ((flow = p->flows)) { | 593 | while ((flow = p->flows)) { |
| 591 | tcf_destroy_chain(flow->filter_list); | ||
| 592 | flow->filter_list = NULL; | ||
| 593 | if (flow->ref > 1) | 594 | if (flow->ref > 1) |
| 594 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow, | 595 | printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow, |
| 595 | flow->ref); | 596 | flow->ref); |
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 09969c1fbc08..2a3c97f7dc63 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
| @@ -1704,7 +1704,7 @@ static void cbq_destroy_class(struct Qdisc *sch, struct cbq_class *cl) | |||
| 1704 | 1704 | ||
| 1705 | BUG_TRAP(!cl->filters); | 1705 | BUG_TRAP(!cl->filters); |
| 1706 | 1706 | ||
| 1707 | tcf_destroy_chain(cl->filter_list); | 1707 | tcf_destroy_chain(&cl->filter_list); |
| 1708 | qdisc_destroy(cl->q); | 1708 | qdisc_destroy(cl->q); |
| 1709 | qdisc_put_rtab(cl->R_tab); | 1709 | qdisc_put_rtab(cl->R_tab); |
| 1710 | gen_kill_estimator(&cl->bstats, &cl->rate_est); | 1710 | gen_kill_estimator(&cl->bstats, &cl->rate_est); |
| @@ -1728,10 +1728,8 @@ cbq_destroy(struct Qdisc* sch) | |||
| 1728 | * be bound to classes which have been destroyed already. --TGR '04 | 1728 | * be bound to classes which have been destroyed already. --TGR '04 |
| 1729 | */ | 1729 | */ |
| 1730 | for (h = 0; h < 16; h++) { | 1730 | for (h = 0; h < 16; h++) { |
| 1731 | for (cl = q->classes[h]; cl; cl = cl->next) { | 1731 | for (cl = q->classes[h]; cl; cl = cl->next) |
| 1732 | tcf_destroy_chain(cl->filter_list); | 1732 | tcf_destroy_chain(&cl->filter_list); |
| 1733 | cl->filter_list = NULL; | ||
| 1734 | } | ||
| 1735 | } | 1733 | } |
| 1736 | for (h = 0; h < 16; h++) { | 1734 | for (h = 0; h < 16; h++) { |
| 1737 | struct cbq_class *next; | 1735 | struct cbq_class *next; |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 64465bacbe79..c4c1317cd47d 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
| @@ -416,7 +416,7 @@ static void dsmark_destroy(struct Qdisc *sch) | |||
| 416 | 416 | ||
| 417 | pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); | 417 | pr_debug("dsmark_destroy(sch %p,[qdisc %p])\n", sch, p); |
| 418 | 418 | ||
| 419 | tcf_destroy_chain(p->filter_list); | 419 | tcf_destroy_chain(&p->filter_list); |
| 420 | qdisc_destroy(p->q); | 420 | qdisc_destroy(p->q); |
| 421 | kfree(p->mask); | 421 | kfree(p->mask); |
| 422 | } | 422 | } |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index d355e5e47fe3..13afa7214392 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
| @@ -468,7 +468,7 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) | |||
| 468 | 468 | ||
| 469 | return sch; | 469 | return sch; |
| 470 | errout: | 470 | errout: |
| 471 | return ERR_PTR(-err); | 471 | return ERR_PTR(err); |
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, | 474 | struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops, |
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index fdfaa3fcc16d..e817aa00441d 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c | |||
| @@ -1123,7 +1123,7 @@ hfsc_destroy_class(struct Qdisc *sch, struct hfsc_class *cl) | |||
| 1123 | { | 1123 | { |
| 1124 | struct hfsc_sched *q = qdisc_priv(sch); | 1124 | struct hfsc_sched *q = qdisc_priv(sch); |
| 1125 | 1125 | ||
| 1126 | tcf_destroy_chain(cl->filter_list); | 1126 | tcf_destroy_chain(&cl->filter_list); |
| 1127 | qdisc_destroy(cl->qdisc); | 1127 | qdisc_destroy(cl->qdisc); |
| 1128 | gen_kill_estimator(&cl->bstats, &cl->rate_est); | 1128 | gen_kill_estimator(&cl->bstats, &cl->rate_est); |
| 1129 | if (cl != &q->root) | 1129 | if (cl != &q->root) |
| @@ -1541,6 +1541,10 @@ hfsc_destroy_qdisc(struct Qdisc *sch) | |||
| 1541 | unsigned int i; | 1541 | unsigned int i; |
| 1542 | 1542 | ||
| 1543 | for (i = 0; i < HFSC_HSIZE; i++) { | 1543 | for (i = 0; i < HFSC_HSIZE; i++) { |
| 1544 | list_for_each_entry(cl, &q->clhash[i], hlist) | ||
| 1545 | tcf_destroy_chain(&cl->filter_list); | ||
| 1546 | } | ||
| 1547 | for (i = 0; i < HFSC_HSIZE; i++) { | ||
| 1544 | list_for_each_entry_safe(cl, next, &q->clhash[i], hlist) | 1548 | list_for_each_entry_safe(cl, next, &q->clhash[i], hlist) |
| 1545 | hfsc_destroy_class(sch, cl); | 1549 | hfsc_destroy_class(sch, cl); |
| 1546 | } | 1550 | } |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 6807c97985a5..3fb58f428f72 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
| @@ -1238,7 +1238,7 @@ static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) | |||
| 1238 | qdisc_put_rtab(cl->rate); | 1238 | qdisc_put_rtab(cl->rate); |
| 1239 | qdisc_put_rtab(cl->ceil); | 1239 | qdisc_put_rtab(cl->ceil); |
| 1240 | 1240 | ||
| 1241 | tcf_destroy_chain(cl->filter_list); | 1241 | tcf_destroy_chain(&cl->filter_list); |
| 1242 | 1242 | ||
| 1243 | while (!list_empty(&cl->children)) | 1243 | while (!list_empty(&cl->children)) |
| 1244 | htb_destroy_class(sch, list_entry(cl->children.next, | 1244 | htb_destroy_class(sch, list_entry(cl->children.next, |
| @@ -1267,7 +1267,7 @@ static void htb_destroy(struct Qdisc *sch) | |||
| 1267 | and surprisingly it worked in 2.4. But it must precede it | 1267 | and surprisingly it worked in 2.4. But it must precede it |
| 1268 | because filter need its target class alive to be able to call | 1268 | because filter need its target class alive to be able to call |
| 1269 | unbind_filter on it (without Oops). */ | 1269 | unbind_filter on it (without Oops). */ |
| 1270 | tcf_destroy_chain(q->filter_list); | 1270 | tcf_destroy_chain(&q->filter_list); |
| 1271 | 1271 | ||
| 1272 | while (!list_empty(&q->root)) | 1272 | while (!list_empty(&q->root)) |
| 1273 | htb_destroy_class(sch, list_entry(q->root.next, | 1273 | htb_destroy_class(sch, list_entry(q->root.next, |
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 274b1ddb160c..956c80ad5965 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c | |||
| @@ -104,7 +104,7 @@ static void ingress_destroy(struct Qdisc *sch) | |||
| 104 | { | 104 | { |
| 105 | struct ingress_qdisc_data *p = qdisc_priv(sch); | 105 | struct ingress_qdisc_data *p = qdisc_priv(sch); |
| 106 | 106 | ||
| 107 | tcf_destroy_chain(p->filter_list); | 107 | tcf_destroy_chain(&p->filter_list); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) | 110 | static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 4aa2b45dad0a..5532f1031ab5 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
| @@ -219,7 +219,7 @@ prio_destroy(struct Qdisc* sch) | |||
| 219 | int prio; | 219 | int prio; |
| 220 | struct prio_sched_data *q = qdisc_priv(sch); | 220 | struct prio_sched_data *q = qdisc_priv(sch); |
| 221 | 221 | ||
| 222 | tcf_destroy_chain(q->filter_list); | 222 | tcf_destroy_chain(&q->filter_list); |
| 223 | for (prio=0; prio<q->bands; prio++) | 223 | for (prio=0; prio<q->bands; prio++) |
| 224 | qdisc_destroy(q->queues[prio]); | 224 | qdisc_destroy(q->queues[prio]); |
| 225 | } | 225 | } |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index f0463d757a98..6a97afbfb952 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
| @@ -520,7 +520,7 @@ static void sfq_destroy(struct Qdisc *sch) | |||
| 520 | { | 520 | { |
| 521 | struct sfq_sched_data *q = qdisc_priv(sch); | 521 | struct sfq_sched_data *q = qdisc_priv(sch); |
| 522 | 522 | ||
| 523 | tcf_destroy_chain(q->filter_list); | 523 | tcf_destroy_chain(&q->filter_list); |
| 524 | q->perturb_period = 0; | 524 | q->perturb_period = 0; |
| 525 | del_timer_sync(&q->perturb_timer); | 525 | del_timer_sync(&q->perturb_timer); |
| 526 | } | 526 | } |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 0c9d5a6950fe..fcdb45d1071b 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -5899,12 +5899,6 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5899 | return SCTP_IERROR_NO_DATA; | 5899 | return SCTP_IERROR_NO_DATA; |
| 5900 | } | 5900 | } |
| 5901 | 5901 | ||
| 5902 | /* If definately accepting the DATA chunk, record its TSN, otherwise | ||
| 5903 | * wait for renege processing. | ||
| 5904 | */ | ||
| 5905 | if (SCTP_CMD_CHUNK_ULP == deliver) | ||
| 5906 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); | ||
| 5907 | |||
| 5908 | chunk->data_accepted = 1; | 5902 | chunk->data_accepted = 1; |
| 5909 | 5903 | ||
| 5910 | /* Note: Some chunks may get overcounted (if we drop) or overcounted | 5904 | /* Note: Some chunks may get overcounted (if we drop) or overcounted |
| @@ -5924,6 +5918,9 @@ static int sctp_eat_data(const struct sctp_association *asoc, | |||
| 5924 | * and discard the DATA chunk. | 5918 | * and discard the DATA chunk. |
| 5925 | */ | 5919 | */ |
| 5926 | if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) { | 5920 | if (ntohs(data_hdr->stream) >= asoc->c.sinit_max_instreams) { |
| 5921 | /* Mark tsn as received even though we drop it */ | ||
| 5922 | sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); | ||
| 5923 | |||
| 5927 | err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM, | 5924 | err = sctp_make_op_error(asoc, chunk, SCTP_ERROR_INV_STRM, |
| 5928 | &data_hdr->stream, | 5925 | &data_hdr->stream, |
| 5929 | sizeof(data_hdr->stream)); | 5926 | sizeof(data_hdr->stream)); |
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index ce6cda6b6994..a1f654aea268 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
| @@ -710,6 +710,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc, | |||
| 710 | if (!skb) | 710 | if (!skb) |
| 711 | goto fail; | 711 | goto fail; |
| 712 | 712 | ||
| 713 | /* Now that all memory allocations for this chunk succeeded, we | ||
| 714 | * can mark it as received so the tsn_map is updated correctly. | ||
| 715 | */ | ||
| 716 | sctp_tsnmap_mark(&asoc->peer.tsn_map, ntohl(chunk->subh.data_hdr->tsn)); | ||
| 717 | |||
| 713 | /* First calculate the padding, so we don't inadvertently | 718 | /* First calculate the padding, so we don't inadvertently |
| 714 | * pass up the wrong length to the user. | 719 | * pass up the wrong length to the user. |
| 715 | * | 720 | * |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index cc12d5f5d5da..834a83199bdf 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -63,22 +63,11 @@ static const struct rpc_credops gss_nullops; | |||
| 63 | # define RPCDBG_FACILITY RPCDBG_AUTH | 63 | # define RPCDBG_FACILITY RPCDBG_AUTH |
| 64 | #endif | 64 | #endif |
| 65 | 65 | ||
| 66 | #define NFS_NGROUPS 16 | 66 | #define GSS_CRED_SLACK 1024 |
| 67 | |||
| 68 | #define GSS_CRED_SLACK 1024 /* XXX: unused */ | ||
| 69 | /* length of a krb5 verifier (48), plus data added before arguments when | 67 | /* length of a krb5 verifier (48), plus data added before arguments when |
| 70 | * using integrity (two 4-byte integers): */ | 68 | * using integrity (two 4-byte integers): */ |
| 71 | #define GSS_VERF_SLACK 100 | 69 | #define GSS_VERF_SLACK 100 |
| 72 | 70 | ||
| 73 | /* XXX this define must match the gssd define | ||
| 74 | * as it is passed to gssd to signal the use of | ||
| 75 | * machine creds should be part of the shared rpc interface */ | ||
| 76 | |||
| 77 | #define CA_RUN_AS_MACHINE 0x00000200 | ||
| 78 | |||
| 79 | /* dump the buffer in `emacs-hexl' style */ | ||
| 80 | #define isprint(c) ((c > 0x1f) && (c < 0x7f)) | ||
| 81 | |||
| 82 | struct gss_auth { | 71 | struct gss_auth { |
| 83 | struct kref kref; | 72 | struct kref kref; |
| 84 | struct rpc_auth rpc_auth; | 73 | struct rpc_auth rpc_auth; |
| @@ -146,7 +135,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) | |||
| 146 | q = (const void *)((const char *)p + len); | 135 | q = (const void *)((const char *)p + len); |
| 147 | if (unlikely(q > end || q < p)) | 136 | if (unlikely(q > end || q < p)) |
| 148 | return ERR_PTR(-EFAULT); | 137 | return ERR_PTR(-EFAULT); |
| 149 | dest->data = kmemdup(p, len, GFP_KERNEL); | 138 | dest->data = kmemdup(p, len, GFP_NOFS); |
| 150 | if (unlikely(dest->data == NULL)) | 139 | if (unlikely(dest->data == NULL)) |
| 151 | return ERR_PTR(-ENOMEM); | 140 | return ERR_PTR(-ENOMEM); |
| 152 | dest->len = len; | 141 | dest->len = len; |
| @@ -171,7 +160,7 @@ gss_alloc_context(void) | |||
| 171 | { | 160 | { |
| 172 | struct gss_cl_ctx *ctx; | 161 | struct gss_cl_ctx *ctx; |
| 173 | 162 | ||
| 174 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 163 | ctx = kzalloc(sizeof(*ctx), GFP_NOFS); |
| 175 | if (ctx != NULL) { | 164 | if (ctx != NULL) { |
| 176 | ctx->gc_proc = RPC_GSS_PROC_DATA; | 165 | ctx->gc_proc = RPC_GSS_PROC_DATA; |
| 177 | ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ | 166 | ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ |
| @@ -272,7 +261,7 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | |||
| 272 | return NULL; | 261 | return NULL; |
| 273 | } | 262 | } |
| 274 | 263 | ||
| 275 | /* Try to add a upcall to the pipefs queue. | 264 | /* Try to add an upcall to the pipefs queue. |
| 276 | * If an upcall owned by our uid already exists, then we return a reference | 265 | * If an upcall owned by our uid already exists, then we return a reference |
| 277 | * to that upcall instead of adding the new upcall. | 266 | * to that upcall instead of adding the new upcall. |
| 278 | */ | 267 | */ |
| @@ -341,7 +330,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) | |||
| 341 | { | 330 | { |
| 342 | struct gss_upcall_msg *gss_msg; | 331 | struct gss_upcall_msg *gss_msg; |
| 343 | 332 | ||
| 344 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL); | 333 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); |
| 345 | if (gss_msg != NULL) { | 334 | if (gss_msg != NULL) { |
| 346 | INIT_LIST_HEAD(&gss_msg->list); | 335 | INIT_LIST_HEAD(&gss_msg->list); |
| 347 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | 336 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); |
| @@ -493,7 +482,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 493 | { | 482 | { |
| 494 | const void *p, *end; | 483 | const void *p, *end; |
| 495 | void *buf; | 484 | void *buf; |
| 496 | struct rpc_clnt *clnt; | ||
| 497 | struct gss_upcall_msg *gss_msg; | 485 | struct gss_upcall_msg *gss_msg; |
| 498 | struct inode *inode = filp->f_path.dentry->d_inode; | 486 | struct inode *inode = filp->f_path.dentry->d_inode; |
| 499 | struct gss_cl_ctx *ctx; | 487 | struct gss_cl_ctx *ctx; |
| @@ -503,11 +491,10 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 503 | if (mlen > MSG_BUF_MAXSIZE) | 491 | if (mlen > MSG_BUF_MAXSIZE) |
| 504 | goto out; | 492 | goto out; |
| 505 | err = -ENOMEM; | 493 | err = -ENOMEM; |
| 506 | buf = kmalloc(mlen, GFP_KERNEL); | 494 | buf = kmalloc(mlen, GFP_NOFS); |
| 507 | if (!buf) | 495 | if (!buf) |
| 508 | goto out; | 496 | goto out; |
| 509 | 497 | ||
| 510 | clnt = RPC_I(inode)->private; | ||
| 511 | err = -EFAULT; | 498 | err = -EFAULT; |
| 512 | if (copy_from_user(buf, src, mlen)) | 499 | if (copy_from_user(buf, src, mlen)) |
| 513 | goto err; | 500 | goto err; |
| @@ -806,7 +793,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
| 806 | dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", | 793 | dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", |
| 807 | acred->uid, auth->au_flavor); | 794 | acred->uid, auth->au_flavor); |
| 808 | 795 | ||
| 809 | if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) | 796 | if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) |
| 810 | goto out_err; | 797 | goto out_err; |
| 811 | 798 | ||
| 812 | rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); | 799 | rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 60c3dba545d7..ef45eba22485 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
| @@ -70,7 +70,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) | |||
| 70 | q = (const void *)((const char *)p + len); | 70 | q = (const void *)((const char *)p + len); |
| 71 | if (unlikely(q > end || q < p)) | 71 | if (unlikely(q > end || q < p)) |
| 72 | return ERR_PTR(-EFAULT); | 72 | return ERR_PTR(-EFAULT); |
| 73 | res->data = kmemdup(p, len, GFP_KERNEL); | 73 | res->data = kmemdup(p, len, GFP_NOFS); |
| 74 | if (unlikely(res->data == NULL)) | 74 | if (unlikely(res->data == NULL)) |
| 75 | return ERR_PTR(-ENOMEM); | 75 | return ERR_PTR(-ENOMEM); |
| 76 | res->len = len; | 76 | res->len = len; |
| @@ -131,7 +131,7 @@ gss_import_sec_context_kerberos(const void *p, | |||
| 131 | struct krb5_ctx *ctx; | 131 | struct krb5_ctx *ctx; |
| 132 | int tmp; | 132 | int tmp; |
| 133 | 133 | ||
| 134 | if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) | 134 | if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) |
| 135 | goto out_err; | 135 | goto out_err; |
| 136 | 136 | ||
| 137 | p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); | 137 | p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c index 5deb4b6e4514..035e1dd6af1b 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c | |||
| @@ -76,7 +76,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) | |||
| 76 | q = (const void *)((const char *)p + len); | 76 | q = (const void *)((const char *)p + len); |
| 77 | if (unlikely(q > end || q < p)) | 77 | if (unlikely(q > end || q < p)) |
| 78 | return ERR_PTR(-EFAULT); | 78 | return ERR_PTR(-EFAULT); |
| 79 | res->data = kmemdup(p, len, GFP_KERNEL); | 79 | res->data = kmemdup(p, len, GFP_NOFS); |
| 80 | if (unlikely(res->data == NULL)) | 80 | if (unlikely(res->data == NULL)) |
| 81 | return ERR_PTR(-ENOMEM); | 81 | return ERR_PTR(-ENOMEM); |
| 82 | return q; | 82 | return q; |
| @@ -90,7 +90,7 @@ gss_import_sec_context_spkm3(const void *p, size_t len, | |||
| 90 | struct spkm3_ctx *ctx; | 90 | struct spkm3_ctx *ctx; |
| 91 | int version; | 91 | int version; |
| 92 | 92 | ||
| 93 | if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) | 93 | if (!(ctx = kzalloc(sizeof(*ctx), GFP_NOFS))) |
| 94 | goto out_err; | 94 | goto out_err; |
| 95 | 95 | ||
| 96 | p = simple_get_bytes(p, end, &version, sizeof(version)); | 96 | p = simple_get_bytes(p, end, &version, sizeof(version)); |
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c index 6cdd241ad267..3308157436d2 100644 --- a/net/sunrpc/auth_gss/gss_spkm3_token.c +++ b/net/sunrpc/auth_gss/gss_spkm3_token.c | |||
| @@ -90,7 +90,7 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits) | |||
| 90 | int | 90 | int |
| 91 | decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen) | 91 | decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen) |
| 92 | { | 92 | { |
| 93 | if (!(out->data = kzalloc(explen,GFP_KERNEL))) | 93 | if (!(out->data = kzalloc(explen,GFP_NOFS))) |
| 94 | return 0; | 94 | return 0; |
| 95 | out->len = explen; | 95 | out->len = explen; |
| 96 | memcpy(out->data, in, enclen); | 96 | memcpy(out->data, in, enclen); |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 5905d56737d6..81ae3d62a0cc 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -1144,20 +1144,20 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 1144 | case RPC_GSS_SVC_NONE: | 1144 | case RPC_GSS_SVC_NONE: |
| 1145 | break; | 1145 | break; |
| 1146 | case RPC_GSS_SVC_INTEGRITY: | 1146 | case RPC_GSS_SVC_INTEGRITY: |
| 1147 | /* placeholders for length and seq. number: */ | ||
| 1148 | svc_putnl(resv, 0); | ||
| 1149 | svc_putnl(resv, 0); | ||
| 1147 | if (unwrap_integ_data(&rqstp->rq_arg, | 1150 | if (unwrap_integ_data(&rqstp->rq_arg, |
| 1148 | gc->gc_seq, rsci->mechctx)) | 1151 | gc->gc_seq, rsci->mechctx)) |
| 1149 | goto garbage_args; | 1152 | goto garbage_args; |
| 1153 | break; | ||
| 1154 | case RPC_GSS_SVC_PRIVACY: | ||
| 1150 | /* placeholders for length and seq. number: */ | 1155 | /* placeholders for length and seq. number: */ |
| 1151 | svc_putnl(resv, 0); | 1156 | svc_putnl(resv, 0); |
| 1152 | svc_putnl(resv, 0); | 1157 | svc_putnl(resv, 0); |
| 1153 | break; | ||
| 1154 | case RPC_GSS_SVC_PRIVACY: | ||
| 1155 | if (unwrap_priv_data(rqstp, &rqstp->rq_arg, | 1158 | if (unwrap_priv_data(rqstp, &rqstp->rq_arg, |
| 1156 | gc->gc_seq, rsci->mechctx)) | 1159 | gc->gc_seq, rsci->mechctx)) |
| 1157 | goto garbage_args; | 1160 | goto garbage_args; |
| 1158 | /* placeholders for length and seq. number: */ | ||
| 1159 | svc_putnl(resv, 0); | ||
| 1160 | svc_putnl(resv, 0); | ||
| 1161 | break; | 1161 | break; |
| 1162 | default: | 1162 | default: |
| 1163 | goto auth_err; | 1163 | goto auth_err; |
| @@ -1170,8 +1170,6 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
| 1170 | goto out; | 1170 | goto out; |
| 1171 | } | 1171 | } |
| 1172 | garbage_args: | 1172 | garbage_args: |
| 1173 | /* Restore write pointer to its original value: */ | ||
| 1174 | xdr_ressize_check(rqstp, reject_stat); | ||
| 1175 | ret = SVC_GARBAGE; | 1173 | ret = SVC_GARBAGE; |
| 1176 | goto out; | 1174 | goto out; |
| 1177 | auth_err: | 1175 | auth_err: |
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 44920b90bdc4..46b2647c5bd2 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c | |||
| @@ -66,7 +66,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
| 66 | dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", | 66 | dprintk("RPC: allocating UNIX cred for uid %d gid %d\n", |
| 67 | acred->uid, acred->gid); | 67 | acred->uid, acred->gid); |
| 68 | 68 | ||
| 69 | if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL))) | 69 | if (!(cred = kmalloc(sizeof(*cred), GFP_NOFS))) |
| 70 | return ERR_PTR(-ENOMEM); | 70 | return ERR_PTR(-ENOMEM); |
| 71 | 71 | ||
| 72 | rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); | 72 | rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops); |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 8945307556ec..76739e928d0d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 28 | #include <linux/kallsyms.h> | ||
| 28 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
| 29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 30 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
| @@ -58,7 +59,6 @@ static void call_start(struct rpc_task *task); | |||
| 58 | static void call_reserve(struct rpc_task *task); | 59 | static void call_reserve(struct rpc_task *task); |
| 59 | static void call_reserveresult(struct rpc_task *task); | 60 | static void call_reserveresult(struct rpc_task *task); |
| 60 | static void call_allocate(struct rpc_task *task); | 61 | static void call_allocate(struct rpc_task *task); |
| 61 | static void call_encode(struct rpc_task *task); | ||
| 62 | static void call_decode(struct rpc_task *task); | 62 | static void call_decode(struct rpc_task *task); |
| 63 | static void call_bind(struct rpc_task *task); | 63 | static void call_bind(struct rpc_task *task); |
| 64 | static void call_bind_status(struct rpc_task *task); | 64 | static void call_bind_status(struct rpc_task *task); |
| @@ -70,9 +70,9 @@ static void call_refreshresult(struct rpc_task *task); | |||
| 70 | static void call_timeout(struct rpc_task *task); | 70 | static void call_timeout(struct rpc_task *task); |
| 71 | static void call_connect(struct rpc_task *task); | 71 | static void call_connect(struct rpc_task *task); |
| 72 | static void call_connect_status(struct rpc_task *task); | 72 | static void call_connect_status(struct rpc_task *task); |
| 73 | static __be32 * call_header(struct rpc_task *task); | ||
| 74 | static __be32 * call_verify(struct rpc_task *task); | ||
| 75 | 73 | ||
| 74 | static __be32 *rpc_encode_header(struct rpc_task *task); | ||
| 75 | static __be32 *rpc_verify_header(struct rpc_task *task); | ||
| 76 | static int rpc_ping(struct rpc_clnt *clnt, int flags); | 76 | static int rpc_ping(struct rpc_clnt *clnt, int flags); |
| 77 | 77 | ||
| 78 | static void rpc_register_client(struct rpc_clnt *clnt) | 78 | static void rpc_register_client(struct rpc_clnt *clnt) |
| @@ -324,6 +324,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
| 324 | clnt->cl_autobind = 1; | 324 | clnt->cl_autobind = 1; |
| 325 | if (args->flags & RPC_CLNT_CREATE_DISCRTRY) | 325 | if (args->flags & RPC_CLNT_CREATE_DISCRTRY) |
| 326 | clnt->cl_discrtry = 1; | 326 | clnt->cl_discrtry = 1; |
| 327 | if (!(args->flags & RPC_CLNT_CREATE_QUIET)) | ||
| 328 | clnt->cl_chatty = 1; | ||
| 327 | 329 | ||
| 328 | return clnt; | 330 | return clnt; |
| 329 | } | 331 | } |
| @@ -690,6 +692,21 @@ rpc_restart_call(struct rpc_task *task) | |||
| 690 | } | 692 | } |
| 691 | EXPORT_SYMBOL_GPL(rpc_restart_call); | 693 | EXPORT_SYMBOL_GPL(rpc_restart_call); |
| 692 | 694 | ||
| 695 | #ifdef RPC_DEBUG | ||
| 696 | static const char *rpc_proc_name(const struct rpc_task *task) | ||
| 697 | { | ||
| 698 | const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; | ||
| 699 | |||
| 700 | if (proc) { | ||
| 701 | if (proc->p_name) | ||
| 702 | return proc->p_name; | ||
| 703 | else | ||
| 704 | return "NULL"; | ||
| 705 | } else | ||
| 706 | return "no proc"; | ||
| 707 | } | ||
| 708 | #endif | ||
| 709 | |||
| 693 | /* | 710 | /* |
| 694 | * 0. Initial state | 711 | * 0. Initial state |
| 695 | * | 712 | * |
| @@ -701,9 +718,9 @@ call_start(struct rpc_task *task) | |||
| 701 | { | 718 | { |
| 702 | struct rpc_clnt *clnt = task->tk_client; | 719 | struct rpc_clnt *clnt = task->tk_client; |
| 703 | 720 | ||
| 704 | dprintk("RPC: %5u call_start %s%d proc %d (%s)\n", task->tk_pid, | 721 | dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid, |
| 705 | clnt->cl_protname, clnt->cl_vers, | 722 | clnt->cl_protname, clnt->cl_vers, |
| 706 | task->tk_msg.rpc_proc->p_proc, | 723 | rpc_proc_name(task), |
| 707 | (RPC_IS_ASYNC(task) ? "async" : "sync")); | 724 | (RPC_IS_ASYNC(task) ? "async" : "sync")); |
| 708 | 725 | ||
| 709 | /* Increment call count */ | 726 | /* Increment call count */ |
| @@ -861,7 +878,7 @@ rpc_xdr_buf_init(struct xdr_buf *buf, void *start, size_t len) | |||
| 861 | * 3. Encode arguments of an RPC call | 878 | * 3. Encode arguments of an RPC call |
| 862 | */ | 879 | */ |
| 863 | static void | 880 | static void |
| 864 | call_encode(struct rpc_task *task) | 881 | rpc_xdr_encode(struct rpc_task *task) |
| 865 | { | 882 | { |
| 866 | struct rpc_rqst *req = task->tk_rqstp; | 883 | struct rpc_rqst *req = task->tk_rqstp; |
| 867 | kxdrproc_t encode; | 884 | kxdrproc_t encode; |
| @@ -876,23 +893,19 @@ call_encode(struct rpc_task *task) | |||
| 876 | (char *)req->rq_buffer + req->rq_callsize, | 893 | (char *)req->rq_buffer + req->rq_callsize, |
| 877 | req->rq_rcvsize); | 894 | req->rq_rcvsize); |
| 878 | 895 | ||
| 879 | /* Encode header and provided arguments */ | 896 | p = rpc_encode_header(task); |
| 880 | encode = task->tk_msg.rpc_proc->p_encode; | 897 | if (p == NULL) { |
| 881 | if (!(p = call_header(task))) { | 898 | printk(KERN_INFO "RPC: couldn't encode RPC header, exit EIO\n"); |
| 882 | printk(KERN_INFO "RPC: call_header failed, exit EIO\n"); | ||
| 883 | rpc_exit(task, -EIO); | 899 | rpc_exit(task, -EIO); |
| 884 | return; | 900 | return; |
| 885 | } | 901 | } |
| 902 | |||
| 903 | encode = task->tk_msg.rpc_proc->p_encode; | ||
| 886 | if (encode == NULL) | 904 | if (encode == NULL) |
| 887 | return; | 905 | return; |
| 888 | 906 | ||
| 889 | task->tk_status = rpcauth_wrap_req(task, encode, req, p, | 907 | task->tk_status = rpcauth_wrap_req(task, encode, req, p, |
| 890 | task->tk_msg.rpc_argp); | 908 | task->tk_msg.rpc_argp); |
| 891 | if (task->tk_status == -ENOMEM) { | ||
| 892 | /* XXX: Is this sane? */ | ||
| 893 | rpc_delay(task, 3*HZ); | ||
| 894 | task->tk_status = -EAGAIN; | ||
| 895 | } | ||
| 896 | } | 909 | } |
| 897 | 910 | ||
| 898 | /* | 911 | /* |
| @@ -929,11 +942,9 @@ call_bind_status(struct rpc_task *task) | |||
| 929 | } | 942 | } |
| 930 | 943 | ||
| 931 | switch (task->tk_status) { | 944 | switch (task->tk_status) { |
| 932 | case -EAGAIN: | 945 | case -ENOMEM: |
| 933 | dprintk("RPC: %5u rpcbind waiting for another request " | 946 | dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid); |
| 934 | "to finish\n", task->tk_pid); | 947 | rpc_delay(task, HZ >> 2); |
| 935 | /* avoid busy-waiting here -- could be a network outage. */ | ||
| 936 | rpc_delay(task, 5*HZ); | ||
| 937 | goto retry_timeout; | 948 | goto retry_timeout; |
| 938 | case -EACCES: | 949 | case -EACCES: |
| 939 | dprintk("RPC: %5u remote rpcbind: RPC program/version " | 950 | dprintk("RPC: %5u remote rpcbind: RPC program/version " |
| @@ -1046,10 +1057,16 @@ call_transmit(struct rpc_task *task) | |||
| 1046 | /* Encode here so that rpcsec_gss can use correct sequence number. */ | 1057 | /* Encode here so that rpcsec_gss can use correct sequence number. */ |
| 1047 | if (rpc_task_need_encode(task)) { | 1058 | if (rpc_task_need_encode(task)) { |
| 1048 | BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); | 1059 | BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); |
| 1049 | call_encode(task); | 1060 | rpc_xdr_encode(task); |
| 1050 | /* Did the encode result in an error condition? */ | 1061 | /* Did the encode result in an error condition? */ |
| 1051 | if (task->tk_status != 0) | 1062 | if (task->tk_status != 0) { |
| 1063 | /* Was the error nonfatal? */ | ||
| 1064 | if (task->tk_status == -EAGAIN) | ||
| 1065 | rpc_delay(task, HZ >> 4); | ||
| 1066 | else | ||
| 1067 | rpc_exit(task, task->tk_status); | ||
| 1052 | return; | 1068 | return; |
| 1069 | } | ||
| 1053 | } | 1070 | } |
| 1054 | xprt_transmit(task); | 1071 | xprt_transmit(task); |
| 1055 | if (task->tk_status < 0) | 1072 | if (task->tk_status < 0) |
| @@ -1132,7 +1149,8 @@ call_status(struct rpc_task *task) | |||
| 1132 | rpc_exit(task, status); | 1149 | rpc_exit(task, status); |
| 1133 | break; | 1150 | break; |
| 1134 | default: | 1151 | default: |
| 1135 | printk("%s: RPC call returned error %d\n", | 1152 | if (clnt->cl_chatty) |
| 1153 | printk("%s: RPC call returned error %d\n", | ||
| 1136 | clnt->cl_protname, -status); | 1154 | clnt->cl_protname, -status); |
| 1137 | rpc_exit(task, status); | 1155 | rpc_exit(task, status); |
| 1138 | } | 1156 | } |
| @@ -1157,7 +1175,8 @@ call_timeout(struct rpc_task *task) | |||
| 1157 | task->tk_timeouts++; | 1175 | task->tk_timeouts++; |
| 1158 | 1176 | ||
| 1159 | if (RPC_IS_SOFT(task)) { | 1177 | if (RPC_IS_SOFT(task)) { |
| 1160 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | 1178 | if (clnt->cl_chatty) |
| 1179 | printk(KERN_NOTICE "%s: server %s not responding, timed out\n", | ||
| 1161 | clnt->cl_protname, clnt->cl_server); | 1180 | clnt->cl_protname, clnt->cl_server); |
| 1162 | rpc_exit(task, -EIO); | 1181 | rpc_exit(task, -EIO); |
| 1163 | return; | 1182 | return; |
| @@ -1165,7 +1184,8 @@ call_timeout(struct rpc_task *task) | |||
| 1165 | 1184 | ||
| 1166 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { | 1185 | if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) { |
| 1167 | task->tk_flags |= RPC_CALL_MAJORSEEN; | 1186 | task->tk_flags |= RPC_CALL_MAJORSEEN; |
| 1168 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | 1187 | if (clnt->cl_chatty) |
| 1188 | printk(KERN_NOTICE "%s: server %s not responding, still trying\n", | ||
| 1169 | clnt->cl_protname, clnt->cl_server); | 1189 | clnt->cl_protname, clnt->cl_server); |
| 1170 | } | 1190 | } |
| 1171 | rpc_force_rebind(clnt); | 1191 | rpc_force_rebind(clnt); |
| @@ -1196,8 +1216,9 @@ call_decode(struct rpc_task *task) | |||
| 1196 | task->tk_pid, task->tk_status); | 1216 | task->tk_pid, task->tk_status); |
| 1197 | 1217 | ||
| 1198 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { | 1218 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
| 1199 | printk(KERN_NOTICE "%s: server %s OK\n", | 1219 | if (clnt->cl_chatty) |
| 1200 | clnt->cl_protname, clnt->cl_server); | 1220 | printk(KERN_NOTICE "%s: server %s OK\n", |
| 1221 | clnt->cl_protname, clnt->cl_server); | ||
| 1201 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; | 1222 | task->tk_flags &= ~RPC_CALL_MAJORSEEN; |
| 1202 | } | 1223 | } |
| 1203 | 1224 | ||
| @@ -1224,8 +1245,7 @@ call_decode(struct rpc_task *task) | |||
| 1224 | goto out_retry; | 1245 | goto out_retry; |
| 1225 | } | 1246 | } |
| 1226 | 1247 | ||
| 1227 | /* Verify the RPC header */ | 1248 | p = rpc_verify_header(task); |
| 1228 | p = call_verify(task); | ||
| 1229 | if (IS_ERR(p)) { | 1249 | if (IS_ERR(p)) { |
| 1230 | if (p == ERR_PTR(-EAGAIN)) | 1250 | if (p == ERR_PTR(-EAGAIN)) |
| 1231 | goto out_retry; | 1251 | goto out_retry; |
| @@ -1243,7 +1263,7 @@ call_decode(struct rpc_task *task) | |||
| 1243 | return; | 1263 | return; |
| 1244 | out_retry: | 1264 | out_retry: |
| 1245 | task->tk_status = 0; | 1265 | task->tk_status = 0; |
| 1246 | /* Note: call_verify() may have freed the RPC slot */ | 1266 | /* Note: rpc_verify_header() may have freed the RPC slot */ |
| 1247 | if (task->tk_rqstp == req) { | 1267 | if (task->tk_rqstp == req) { |
| 1248 | req->rq_received = req->rq_rcv_buf.len = 0; | 1268 | req->rq_received = req->rq_rcv_buf.len = 0; |
| 1249 | if (task->tk_client->cl_discrtry) | 1269 | if (task->tk_client->cl_discrtry) |
| @@ -1290,11 +1310,8 @@ call_refreshresult(struct rpc_task *task) | |||
| 1290 | return; | 1310 | return; |
| 1291 | } | 1311 | } |
| 1292 | 1312 | ||
| 1293 | /* | ||
| 1294 | * Call header serialization | ||
| 1295 | */ | ||
| 1296 | static __be32 * | 1313 | static __be32 * |
| 1297 | call_header(struct rpc_task *task) | 1314 | rpc_encode_header(struct rpc_task *task) |
| 1298 | { | 1315 | { |
| 1299 | struct rpc_clnt *clnt = task->tk_client; | 1316 | struct rpc_clnt *clnt = task->tk_client; |
| 1300 | struct rpc_rqst *req = task->tk_rqstp; | 1317 | struct rpc_rqst *req = task->tk_rqstp; |
| @@ -1314,11 +1331,8 @@ call_header(struct rpc_task *task) | |||
| 1314 | return p; | 1331 | return p; |
| 1315 | } | 1332 | } |
| 1316 | 1333 | ||
| 1317 | /* | ||
| 1318 | * Reply header verification | ||
| 1319 | */ | ||
| 1320 | static __be32 * | 1334 | static __be32 * |
| 1321 | call_verify(struct rpc_task *task) | 1335 | rpc_verify_header(struct rpc_task *task) |
| 1322 | { | 1336 | { |
| 1323 | struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; | 1337 | struct kvec *iov = &task->tk_rqstp->rq_rcv_buf.head[0]; |
| 1324 | int len = task->tk_rqstp->rq_rcv_buf.len >> 2; | 1338 | int len = task->tk_rqstp->rq_rcv_buf.len >> 2; |
| @@ -1392,7 +1406,7 @@ call_verify(struct rpc_task *task) | |||
| 1392 | task->tk_action = call_bind; | 1406 | task->tk_action = call_bind; |
| 1393 | goto out_retry; | 1407 | goto out_retry; |
| 1394 | case RPC_AUTH_TOOWEAK: | 1408 | case RPC_AUTH_TOOWEAK: |
| 1395 | printk(KERN_NOTICE "call_verify: server %s requires stronger " | 1409 | printk(KERN_NOTICE "RPC: server %s requires stronger " |
| 1396 | "authentication.\n", task->tk_client->cl_server); | 1410 | "authentication.\n", task->tk_client->cl_server); |
| 1397 | break; | 1411 | break; |
| 1398 | default: | 1412 | default: |
| @@ -1431,10 +1445,10 @@ call_verify(struct rpc_task *task) | |||
| 1431 | error = -EPROTONOSUPPORT; | 1445 | error = -EPROTONOSUPPORT; |
| 1432 | goto out_err; | 1446 | goto out_err; |
| 1433 | case RPC_PROC_UNAVAIL: | 1447 | case RPC_PROC_UNAVAIL: |
| 1434 | dprintk("RPC: %5u %s: proc %p unsupported by program %u, " | 1448 | dprintk("RPC: %5u %s: proc %s unsupported by program %u, " |
| 1435 | "version %u on server %s\n", | 1449 | "version %u on server %s\n", |
| 1436 | task->tk_pid, __func__, | 1450 | task->tk_pid, __func__, |
| 1437 | task->tk_msg.rpc_proc, | 1451 | rpc_proc_name(task), |
| 1438 | task->tk_client->cl_prog, | 1452 | task->tk_client->cl_prog, |
| 1439 | task->tk_client->cl_vers, | 1453 | task->tk_client->cl_vers, |
| 1440 | task->tk_client->cl_server); | 1454 | task->tk_client->cl_server); |
| @@ -1517,44 +1531,53 @@ struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred, int | |||
| 1517 | EXPORT_SYMBOL_GPL(rpc_call_null); | 1531 | EXPORT_SYMBOL_GPL(rpc_call_null); |
| 1518 | 1532 | ||
| 1519 | #ifdef RPC_DEBUG | 1533 | #ifdef RPC_DEBUG |
| 1534 | static void rpc_show_header(void) | ||
| 1535 | { | ||
| 1536 | printk(KERN_INFO "-pid- flgs status -client- --rqstp- " | ||
| 1537 | "-timeout ---ops--\n"); | ||
| 1538 | } | ||
| 1539 | |||
| 1540 | static void rpc_show_task(const struct rpc_clnt *clnt, | ||
| 1541 | const struct rpc_task *task) | ||
| 1542 | { | ||
| 1543 | const char *rpc_waitq = "none"; | ||
| 1544 | char *p, action[KSYM_SYMBOL_LEN]; | ||
| 1545 | |||
| 1546 | if (RPC_IS_QUEUED(task)) | ||
| 1547 | rpc_waitq = rpc_qname(task->tk_waitqueue); | ||
| 1548 | |||
| 1549 | /* map tk_action pointer to a function name; then trim off | ||
| 1550 | * the "+0x0 [sunrpc]" */ | ||
| 1551 | sprint_symbol(action, (unsigned long)task->tk_action); | ||
| 1552 | p = strchr(action, '+'); | ||
| 1553 | if (p) | ||
| 1554 | *p = '\0'; | ||
| 1555 | |||
| 1556 | printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", | ||
| 1557 | task->tk_pid, task->tk_flags, task->tk_status, | ||
| 1558 | clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, | ||
| 1559 | clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), | ||
| 1560 | action, rpc_waitq); | ||
| 1561 | } | ||
| 1562 | |||
| 1520 | void rpc_show_tasks(void) | 1563 | void rpc_show_tasks(void) |
| 1521 | { | 1564 | { |
| 1522 | struct rpc_clnt *clnt; | 1565 | struct rpc_clnt *clnt; |
| 1523 | struct rpc_task *t; | 1566 | struct rpc_task *task; |
| 1567 | int header = 0; | ||
| 1524 | 1568 | ||
| 1525 | spin_lock(&rpc_client_lock); | 1569 | spin_lock(&rpc_client_lock); |
| 1526 | if (list_empty(&all_clients)) | ||
| 1527 | goto out; | ||
| 1528 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " | ||
| 1529 | "-rpcwait -action- ---ops--\n"); | ||
| 1530 | list_for_each_entry(clnt, &all_clients, cl_clients) { | 1570 | list_for_each_entry(clnt, &all_clients, cl_clients) { |
| 1531 | if (list_empty(&clnt->cl_tasks)) | ||
| 1532 | continue; | ||
| 1533 | spin_lock(&clnt->cl_lock); | 1571 | spin_lock(&clnt->cl_lock); |
| 1534 | list_for_each_entry(t, &clnt->cl_tasks, tk_task) { | 1572 | list_for_each_entry(task, &clnt->cl_tasks, tk_task) { |
| 1535 | const char *rpc_waitq = "none"; | 1573 | if (!header) { |
| 1536 | int proc; | 1574 | rpc_show_header(); |
| 1537 | 1575 | header++; | |
| 1538 | if (t->tk_msg.rpc_proc) | 1576 | } |
| 1539 | proc = t->tk_msg.rpc_proc->p_proc; | 1577 | rpc_show_task(clnt, task); |
| 1540 | else | ||
| 1541 | proc = -1; | ||
| 1542 | |||
| 1543 | if (RPC_IS_QUEUED(t)) | ||
| 1544 | rpc_waitq = rpc_qname(t->tk_waitqueue); | ||
| 1545 | |||
| 1546 | printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", | ||
| 1547 | t->tk_pid, proc, | ||
| 1548 | t->tk_flags, t->tk_status, | ||
| 1549 | t->tk_client, | ||
| 1550 | (t->tk_client ? t->tk_client->cl_prog : 0), | ||
| 1551 | t->tk_rqstp, t->tk_timeout, | ||
| 1552 | rpc_waitq, | ||
| 1553 | t->tk_action, t->tk_ops); | ||
| 1554 | } | 1578 | } |
| 1555 | spin_unlock(&clnt->cl_lock); | 1579 | spin_unlock(&clnt->cl_lock); |
| 1556 | } | 1580 | } |
| 1557 | out: | ||
| 1558 | spin_unlock(&rpc_client_lock); | 1581 | spin_unlock(&rpc_client_lock); |
| 1559 | } | 1582 | } |
| 1560 | #endif | 1583 | #endif |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 0517967a68bf..24db2b4d12d3 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
| @@ -32,6 +32,10 @@ | |||
| 32 | #define RPCBIND_PROGRAM (100000u) | 32 | #define RPCBIND_PROGRAM (100000u) |
| 33 | #define RPCBIND_PORT (111u) | 33 | #define RPCBIND_PORT (111u) |
| 34 | 34 | ||
| 35 | #define RPCBVERS_2 (2u) | ||
| 36 | #define RPCBVERS_3 (3u) | ||
| 37 | #define RPCBVERS_4 (4u) | ||
| 38 | |||
| 35 | enum { | 39 | enum { |
| 36 | RPCBPROC_NULL, | 40 | RPCBPROC_NULL, |
| 37 | RPCBPROC_SET, | 41 | RPCBPROC_SET, |
| @@ -64,6 +68,7 @@ enum { | |||
| 64 | #define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING) | 68 | #define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING) |
| 65 | 69 | ||
| 66 | static void rpcb_getport_done(struct rpc_task *, void *); | 70 | static void rpcb_getport_done(struct rpc_task *, void *); |
| 71 | static void rpcb_map_release(void *data); | ||
| 67 | static struct rpc_program rpcb_program; | 72 | static struct rpc_program rpcb_program; |
| 68 | 73 | ||
| 69 | struct rpcbind_args { | 74 | struct rpcbind_args { |
| @@ -76,41 +81,73 @@ struct rpcbind_args { | |||
| 76 | const char * r_netid; | 81 | const char * r_netid; |
| 77 | const char * r_addr; | 82 | const char * r_addr; |
| 78 | const char * r_owner; | 83 | const char * r_owner; |
| 84 | |||
| 85 | int r_status; | ||
| 79 | }; | 86 | }; |
| 80 | 87 | ||
| 81 | static struct rpc_procinfo rpcb_procedures2[]; | 88 | static struct rpc_procinfo rpcb_procedures2[]; |
| 82 | static struct rpc_procinfo rpcb_procedures3[]; | 89 | static struct rpc_procinfo rpcb_procedures3[]; |
| 90 | static struct rpc_procinfo rpcb_procedures4[]; | ||
| 83 | 91 | ||
| 84 | struct rpcb_info { | 92 | struct rpcb_info { |
| 85 | int rpc_vers; | 93 | u32 rpc_vers; |
| 86 | struct rpc_procinfo * rpc_proc; | 94 | struct rpc_procinfo * rpc_proc; |
| 87 | }; | 95 | }; |
| 88 | 96 | ||
| 89 | static struct rpcb_info rpcb_next_version[]; | 97 | static struct rpcb_info rpcb_next_version[]; |
| 90 | static struct rpcb_info rpcb_next_version6[]; | 98 | static struct rpcb_info rpcb_next_version6[]; |
| 91 | 99 | ||
| 100 | static const struct rpc_call_ops rpcb_getport_ops = { | ||
| 101 | .rpc_call_done = rpcb_getport_done, | ||
| 102 | .rpc_release = rpcb_map_release, | ||
| 103 | }; | ||
| 104 | |||
| 105 | static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status) | ||
| 106 | { | ||
| 107 | xprt_clear_binding(xprt); | ||
| 108 | rpc_wake_up_status(&xprt->binding, status); | ||
| 109 | } | ||
| 110 | |||
| 92 | static void rpcb_map_release(void *data) | 111 | static void rpcb_map_release(void *data) |
| 93 | { | 112 | { |
| 94 | struct rpcbind_args *map = data; | 113 | struct rpcbind_args *map = data; |
| 95 | 114 | ||
| 115 | rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status); | ||
| 96 | xprt_put(map->r_xprt); | 116 | xprt_put(map->r_xprt); |
| 97 | kfree(map); | 117 | kfree(map); |
| 98 | } | 118 | } |
| 99 | 119 | ||
| 100 | static const struct rpc_call_ops rpcb_getport_ops = { | 120 | static const struct sockaddr_in rpcb_inaddr_loopback = { |
| 101 | .rpc_call_done = rpcb_getport_done, | 121 | .sin_family = AF_INET, |
| 102 | .rpc_release = rpcb_map_release, | 122 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), |
| 123 | .sin_port = htons(RPCBIND_PORT), | ||
| 103 | }; | 124 | }; |
| 104 | 125 | ||
| 105 | static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status) | 126 | static const struct sockaddr_in6 rpcb_in6addr_loopback = { |
| 127 | .sin6_family = AF_INET6, | ||
| 128 | .sin6_addr = IN6ADDR_LOOPBACK_INIT, | ||
| 129 | .sin6_port = htons(RPCBIND_PORT), | ||
| 130 | }; | ||
| 131 | |||
| 132 | static struct rpc_clnt *rpcb_create_local(struct sockaddr *addr, | ||
| 133 | size_t addrlen, u32 version) | ||
| 106 | { | 134 | { |
| 107 | xprt_clear_binding(xprt); | 135 | struct rpc_create_args args = { |
| 108 | rpc_wake_up_status(&xprt->binding, status); | 136 | .protocol = XPRT_TRANSPORT_UDP, |
| 137 | .address = addr, | ||
| 138 | .addrsize = addrlen, | ||
| 139 | .servername = "localhost", | ||
| 140 | .program = &rpcb_program, | ||
| 141 | .version = version, | ||
| 142 | .authflavor = RPC_AUTH_UNIX, | ||
| 143 | .flags = RPC_CLNT_CREATE_NOPING, | ||
| 144 | }; | ||
| 145 | |||
| 146 | return rpc_create(&args); | ||
| 109 | } | 147 | } |
| 110 | 148 | ||
| 111 | static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | 149 | static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, |
| 112 | size_t salen, int proto, u32 version, | 150 | size_t salen, int proto, u32 version) |
| 113 | int privileged) | ||
| 114 | { | 151 | { |
| 115 | struct rpc_create_args args = { | 152 | struct rpc_create_args args = { |
| 116 | .protocol = proto, | 153 | .protocol = proto, |
| @@ -120,7 +157,8 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | |||
| 120 | .program = &rpcb_program, | 157 | .program = &rpcb_program, |
| 121 | .version = version, | 158 | .version = version, |
| 122 | .authflavor = RPC_AUTH_UNIX, | 159 | .authflavor = RPC_AUTH_UNIX, |
| 123 | .flags = RPC_CLNT_CREATE_NOPING, | 160 | .flags = (RPC_CLNT_CREATE_NOPING | |
| 161 | RPC_CLNT_CREATE_NONPRIVPORT), | ||
| 124 | }; | 162 | }; |
| 125 | 163 | ||
| 126 | switch (srvaddr->sa_family) { | 164 | switch (srvaddr->sa_family) { |
| @@ -134,29 +172,72 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | |||
| 134 | return NULL; | 172 | return NULL; |
| 135 | } | 173 | } |
| 136 | 174 | ||
| 137 | if (!privileged) | ||
| 138 | args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; | ||
| 139 | return rpc_create(&args); | 175 | return rpc_create(&args); |
| 140 | } | 176 | } |
| 141 | 177 | ||
| 178 | static int rpcb_register_call(struct sockaddr *addr, size_t addrlen, | ||
| 179 | u32 version, struct rpc_message *msg, | ||
| 180 | int *result) | ||
| 181 | { | ||
| 182 | struct rpc_clnt *rpcb_clnt; | ||
| 183 | int error = 0; | ||
| 184 | |||
| 185 | *result = 0; | ||
| 186 | |||
| 187 | rpcb_clnt = rpcb_create_local(addr, addrlen, version); | ||
| 188 | if (!IS_ERR(rpcb_clnt)) { | ||
| 189 | error = rpc_call_sync(rpcb_clnt, msg, 0); | ||
| 190 | rpc_shutdown_client(rpcb_clnt); | ||
| 191 | } else | ||
| 192 | error = PTR_ERR(rpcb_clnt); | ||
| 193 | |||
| 194 | if (error < 0) | ||
| 195 | printk(KERN_WARNING "RPC: failed to contact local rpcbind " | ||
| 196 | "server (errno %d).\n", -error); | ||
| 197 | dprintk("RPC: registration status %d/%d\n", error, *result); | ||
| 198 | |||
| 199 | return error; | ||
| 200 | } | ||
| 201 | |||
| 142 | /** | 202 | /** |
| 143 | * rpcb_register - set or unset a port registration with the local rpcbind svc | 203 | * rpcb_register - set or unset a port registration with the local rpcbind svc |
| 144 | * @prog: RPC program number to bind | 204 | * @prog: RPC program number to bind |
| 145 | * @vers: RPC version number to bind | 205 | * @vers: RPC version number to bind |
| 146 | * @prot: transport protocol to use to make this request | 206 | * @prot: transport protocol to register |
| 147 | * @port: port value to register | 207 | * @port: port value to register |
| 148 | * @okay: result code | 208 | * @okay: OUT: result code |
| 209 | * | ||
| 210 | * RPC services invoke this function to advertise their contact | ||
| 211 | * information via the system's rpcbind daemon. RPC services | ||
| 212 | * invoke this function once for each [program, version, transport] | ||
| 213 | * tuple they wish to advertise. | ||
| 214 | * | ||
| 215 | * Callers may also unregister RPC services that are no longer | ||
| 216 | * available by setting the passed-in port to zero. This removes | ||
| 217 | * all registered transports for [program, version] from the local | ||
| 218 | * rpcbind database. | ||
| 219 | * | ||
| 220 | * Returns zero if the registration request was dispatched | ||
| 221 | * successfully and a reply was received. The rpcbind daemon's | ||
| 222 | * boolean result code is stored in *okay. | ||
| 223 | * | ||
| 224 | * Returns an errno value and sets *result to zero if there was | ||
| 225 | * some problem that prevented the rpcbind request from being | ||
| 226 | * dispatched, or if the rpcbind daemon did not respond within | ||
| 227 | * the timeout. | ||
| 149 | * | 228 | * |
| 150 | * port == 0 means unregister, port != 0 means register. | 229 | * This function uses rpcbind protocol version 2 to contact the |
| 230 | * local rpcbind daemon. | ||
| 151 | * | 231 | * |
| 152 | * This routine supports only rpcbind version 2. | 232 | * Registration works over both AF_INET and AF_INET6, and services |
| 233 | * registered via this function are advertised as available for any | ||
| 234 | * address. If the local rpcbind daemon is listening on AF_INET6, | ||
| 235 | * services registered via this function will be advertised on | ||
| 236 | * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6 | ||
| 237 | * addresses). | ||
| 153 | */ | 238 | */ |
| 154 | int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) | 239 | int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) |
| 155 | { | 240 | { |
| 156 | struct sockaddr_in sin = { | ||
| 157 | .sin_family = AF_INET, | ||
| 158 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | ||
| 159 | }; | ||
| 160 | struct rpcbind_args map = { | 241 | struct rpcbind_args map = { |
| 161 | .r_prog = prog, | 242 | .r_prog = prog, |
| 162 | .r_vers = vers, | 243 | .r_vers = vers, |
| @@ -164,32 +245,159 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) | |||
| 164 | .r_port = port, | 245 | .r_port = port, |
| 165 | }; | 246 | }; |
| 166 | struct rpc_message msg = { | 247 | struct rpc_message msg = { |
| 167 | .rpc_proc = &rpcb_procedures2[port ? | ||
| 168 | RPCBPROC_SET : RPCBPROC_UNSET], | ||
| 169 | .rpc_argp = &map, | 248 | .rpc_argp = &map, |
| 170 | .rpc_resp = okay, | 249 | .rpc_resp = okay, |
| 171 | }; | 250 | }; |
| 172 | struct rpc_clnt *rpcb_clnt; | ||
| 173 | int error = 0; | ||
| 174 | 251 | ||
| 175 | dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " | 252 | dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " |
| 176 | "rpcbind\n", (port ? "" : "un"), | 253 | "rpcbind\n", (port ? "" : "un"), |
| 177 | prog, vers, prot, port); | 254 | prog, vers, prot, port); |
| 178 | 255 | ||
| 179 | rpcb_clnt = rpcb_create("localhost", (struct sockaddr *) &sin, | 256 | msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET]; |
| 180 | sizeof(sin), XPRT_TRANSPORT_UDP, 2, 1); | 257 | if (port) |
| 181 | if (IS_ERR(rpcb_clnt)) | 258 | msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET]; |
| 182 | return PTR_ERR(rpcb_clnt); | ||
| 183 | 259 | ||
| 184 | error = rpc_call_sync(rpcb_clnt, &msg, 0); | 260 | return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback, |
| 261 | sizeof(rpcb_inaddr_loopback), | ||
| 262 | RPCBVERS_2, &msg, okay); | ||
| 263 | } | ||
| 185 | 264 | ||
| 186 | rpc_shutdown_client(rpcb_clnt); | 265 | /* |
| 187 | if (error < 0) | 266 | * Fill in AF_INET family-specific arguments to register |
| 188 | printk(KERN_WARNING "RPC: failed to contact local rpcbind " | 267 | */ |
| 189 | "server (errno %d).\n", -error); | 268 | static int rpcb_register_netid4(struct sockaddr_in *address_to_register, |
| 190 | dprintk("RPC: registration status %d/%d\n", error, *okay); | 269 | struct rpc_message *msg) |
| 270 | { | ||
| 271 | struct rpcbind_args *map = msg->rpc_argp; | ||
| 272 | unsigned short port = ntohs(address_to_register->sin_port); | ||
| 273 | char buf[32]; | ||
| 274 | |||
| 275 | /* Construct AF_INET universal address */ | ||
| 276 | snprintf(buf, sizeof(buf), | ||
| 277 | NIPQUAD_FMT".%u.%u", | ||
| 278 | NIPQUAD(address_to_register->sin_addr.s_addr), | ||
| 279 | port >> 8, port & 0xff); | ||
| 280 | map->r_addr = buf; | ||
| 281 | |||
| 282 | dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " | ||
| 283 | "local rpcbind\n", (port ? "" : "un"), | ||
| 284 | map->r_prog, map->r_vers, | ||
| 285 | map->r_addr, map->r_netid); | ||
| 286 | |||
| 287 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; | ||
| 288 | if (port) | ||
| 289 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; | ||
| 290 | |||
| 291 | return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback, | ||
| 292 | sizeof(rpcb_inaddr_loopback), | ||
| 293 | RPCBVERS_4, msg, msg->rpc_resp); | ||
| 294 | } | ||
| 191 | 295 | ||
| 192 | return error; | 296 | /* |
| 297 | * Fill in AF_INET6 family-specific arguments to register | ||
| 298 | */ | ||
| 299 | static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register, | ||
| 300 | struct rpc_message *msg) | ||
| 301 | { | ||
| 302 | struct rpcbind_args *map = msg->rpc_argp; | ||
| 303 | unsigned short port = ntohs(address_to_register->sin6_port); | ||
| 304 | char buf[64]; | ||
| 305 | |||
| 306 | /* Construct AF_INET6 universal address */ | ||
| 307 | snprintf(buf, sizeof(buf), | ||
| 308 | NIP6_FMT".%u.%u", | ||
| 309 | NIP6(address_to_register->sin6_addr), | ||
| 310 | port >> 8, port & 0xff); | ||
| 311 | map->r_addr = buf; | ||
| 312 | |||
| 313 | dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " | ||
| 314 | "local rpcbind\n", (port ? "" : "un"), | ||
| 315 | map->r_prog, map->r_vers, | ||
| 316 | map->r_addr, map->r_netid); | ||
| 317 | |||
| 318 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET]; | ||
| 319 | if (port) | ||
| 320 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; | ||
| 321 | |||
| 322 | return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback, | ||
| 323 | sizeof(rpcb_in6addr_loopback), | ||
| 324 | RPCBVERS_4, msg, msg->rpc_resp); | ||
| 325 | } | ||
| 326 | |||
| 327 | /** | ||
| 328 | * rpcb_v4_register - set or unset a port registration with the local rpcbind | ||
| 329 | * @program: RPC program number of service to (un)register | ||
| 330 | * @version: RPC version number of service to (un)register | ||
| 331 | * @address: address family, IP address, and port to (un)register | ||
| 332 | * @netid: netid of transport protocol to (un)register | ||
| 333 | * @result: result code from rpcbind RPC call | ||
| 334 | * | ||
| 335 | * RPC services invoke this function to advertise their contact | ||
| 336 | * information via the system's rpcbind daemon. RPC services | ||
| 337 | * invoke this function once for each [program, version, address, | ||
| 338 | * netid] tuple they wish to advertise. | ||
| 339 | * | ||
| 340 | * Callers may also unregister RPC services that are no longer | ||
| 341 | * available by setting the port number in the passed-in address | ||
| 342 | * to zero. Callers pass a netid of "" to unregister all | ||
| 343 | * transport netids associated with [program, version, address]. | ||
| 344 | * | ||
| 345 | * Returns zero if the registration request was dispatched | ||
| 346 | * successfully and a reply was received. The rpcbind daemon's | ||
| 347 | * result code is stored in *result. | ||
| 348 | * | ||
| 349 | * Returns an errno value and sets *result to zero if there was | ||
| 350 | * some problem that prevented the rpcbind request from being | ||
| 351 | * dispatched, or if the rpcbind daemon did not respond within | ||
| 352 | * the timeout. | ||
| 353 | * | ||
| 354 | * This function uses rpcbind protocol version 4 to contact the | ||
| 355 | * local rpcbind daemon. The local rpcbind daemon must support | ||
| 356 | * version 4 of the rpcbind protocol in order for these functions | ||
| 357 | * to register a service successfully. | ||
| 358 | * | ||
| 359 | * Supported netids include "udp" and "tcp" for UDP and TCP over | ||
| 360 | * IPv4, and "udp6" and "tcp6" for UDP and TCP over IPv6, | ||
| 361 | * respectively. | ||
| 362 | * | ||
| 363 | * The contents of @address determine the address family and the | ||
| 364 | * port to be registered. The usual practice is to pass INADDR_ANY | ||
| 365 | * as the raw address, but specifying a non-zero address is also | ||
| 366 | * supported by this API if the caller wishes to advertise an RPC | ||
| 367 | * service on a specific network interface. | ||
| 368 | * | ||
| 369 | * Note that passing in INADDR_ANY does not create the same service | ||
| 370 | * registration as IN6ADDR_ANY. The former advertises an RPC | ||
| 371 | * service on any IPv4 address, but not on IPv6. The latter | ||
| 372 | * advertises the service on all IPv4 and IPv6 addresses. | ||
| 373 | */ | ||
| 374 | int rpcb_v4_register(const u32 program, const u32 version, | ||
| 375 | const struct sockaddr *address, const char *netid, | ||
| 376 | int *result) | ||
| 377 | { | ||
| 378 | struct rpcbind_args map = { | ||
| 379 | .r_prog = program, | ||
| 380 | .r_vers = version, | ||
| 381 | .r_netid = netid, | ||
| 382 | .r_owner = RPCB_OWNER_STRING, | ||
| 383 | }; | ||
| 384 | struct rpc_message msg = { | ||
| 385 | .rpc_argp = &map, | ||
| 386 | .rpc_resp = result, | ||
| 387 | }; | ||
| 388 | |||
| 389 | *result = 0; | ||
| 390 | |||
| 391 | switch (address->sa_family) { | ||
| 392 | case AF_INET: | ||
| 393 | return rpcb_register_netid4((struct sockaddr_in *)address, | ||
| 394 | &msg); | ||
| 395 | case AF_INET6: | ||
| 396 | return rpcb_register_netid6((struct sockaddr_in6 *)address, | ||
| 397 | &msg); | ||
| 398 | } | ||
| 399 | |||
| 400 | return -EAFNOSUPPORT; | ||
| 193 | } | 401 | } |
| 194 | 402 | ||
| 195 | /** | 403 | /** |
| @@ -227,7 +435,7 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) | |||
| 227 | __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); | 435 | __func__, NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot); |
| 228 | 436 | ||
| 229 | rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, | 437 | rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, |
| 230 | sizeof(*sin), prot, 2, 0); | 438 | sizeof(*sin), prot, RPCBVERS_2); |
| 231 | if (IS_ERR(rpcb_clnt)) | 439 | if (IS_ERR(rpcb_clnt)) |
| 232 | return PTR_ERR(rpcb_clnt); | 440 | return PTR_ERR(rpcb_clnt); |
| 233 | 441 | ||
| @@ -243,10 +451,10 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) | |||
| 243 | } | 451 | } |
| 244 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); | 452 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); |
| 245 | 453 | ||
| 246 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version) | 454 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc) |
| 247 | { | 455 | { |
| 248 | struct rpc_message msg = { | 456 | struct rpc_message msg = { |
| 249 | .rpc_proc = rpcb_next_version[version].rpc_proc, | 457 | .rpc_proc = proc, |
| 250 | .rpc_argp = map, | 458 | .rpc_argp = map, |
| 251 | .rpc_resp = &map->r_port, | 459 | .rpc_resp = &map->r_port, |
| 252 | }; | 460 | }; |
| @@ -271,6 +479,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi | |||
| 271 | void rpcb_getport_async(struct rpc_task *task) | 479 | void rpcb_getport_async(struct rpc_task *task) |
| 272 | { | 480 | { |
| 273 | struct rpc_clnt *clnt = task->tk_client; | 481 | struct rpc_clnt *clnt = task->tk_client; |
| 482 | struct rpc_procinfo *proc; | ||
| 274 | u32 bind_version; | 483 | u32 bind_version; |
| 275 | struct rpc_xprt *xprt = task->tk_xprt; | 484 | struct rpc_xprt *xprt = task->tk_xprt; |
| 276 | struct rpc_clnt *rpcb_clnt; | 485 | struct rpc_clnt *rpcb_clnt; |
| @@ -280,7 +489,6 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 280 | struct sockaddr *sap = (struct sockaddr *)&addr; | 489 | struct sockaddr *sap = (struct sockaddr *)&addr; |
| 281 | size_t salen; | 490 | size_t salen; |
| 282 | int status; | 491 | int status; |
| 283 | struct rpcb_info *info; | ||
| 284 | 492 | ||
| 285 | dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", | 493 | dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", |
| 286 | task->tk_pid, __func__, | 494 | task->tk_pid, __func__, |
| @@ -289,17 +497,16 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 289 | /* Autobind on cloned rpc clients is discouraged */ | 497 | /* Autobind on cloned rpc clients is discouraged */ |
| 290 | BUG_ON(clnt->cl_parent != clnt); | 498 | BUG_ON(clnt->cl_parent != clnt); |
| 291 | 499 | ||
| 500 | /* Put self on the wait queue to ensure we get notified if | ||
| 501 | * some other task is already attempting to bind the port */ | ||
| 502 | rpc_sleep_on(&xprt->binding, task, NULL); | ||
| 503 | |||
| 292 | if (xprt_test_and_set_binding(xprt)) { | 504 | if (xprt_test_and_set_binding(xprt)) { |
| 293 | status = -EAGAIN; /* tell caller to check again */ | ||
| 294 | dprintk("RPC: %5u %s: waiting for another binder\n", | 505 | dprintk("RPC: %5u %s: waiting for another binder\n", |
| 295 | task->tk_pid, __func__); | 506 | task->tk_pid, __func__); |
| 296 | goto bailout_nowake; | 507 | return; |
| 297 | } | 508 | } |
| 298 | 509 | ||
| 299 | /* Put self on queue before sending rpcbind request, in case | ||
| 300 | * rpcb_getport_done completes before we return from rpc_run_task */ | ||
| 301 | rpc_sleep_on(&xprt->binding, task, NULL); | ||
| 302 | |||
| 303 | /* Someone else may have bound if we slept */ | 510 | /* Someone else may have bound if we slept */ |
| 304 | if (xprt_bound(xprt)) { | 511 | if (xprt_bound(xprt)) { |
| 305 | status = 0; | 512 | status = 0; |
| @@ -313,10 +520,12 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 313 | /* Don't ever use rpcbind v2 for AF_INET6 requests */ | 520 | /* Don't ever use rpcbind v2 for AF_INET6 requests */ |
| 314 | switch (sap->sa_family) { | 521 | switch (sap->sa_family) { |
| 315 | case AF_INET: | 522 | case AF_INET: |
| 316 | info = rpcb_next_version; | 523 | proc = rpcb_next_version[xprt->bind_index].rpc_proc; |
| 524 | bind_version = rpcb_next_version[xprt->bind_index].rpc_vers; | ||
| 317 | break; | 525 | break; |
| 318 | case AF_INET6: | 526 | case AF_INET6: |
| 319 | info = rpcb_next_version6; | 527 | proc = rpcb_next_version6[xprt->bind_index].rpc_proc; |
| 528 | bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers; | ||
| 320 | break; | 529 | break; |
| 321 | default: | 530 | default: |
| 322 | status = -EAFNOSUPPORT; | 531 | status = -EAFNOSUPPORT; |
| @@ -324,20 +533,19 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 324 | task->tk_pid, __func__); | 533 | task->tk_pid, __func__); |
| 325 | goto bailout_nofree; | 534 | goto bailout_nofree; |
| 326 | } | 535 | } |
| 327 | if (info[xprt->bind_index].rpc_proc == NULL) { | 536 | if (proc == NULL) { |
| 328 | xprt->bind_index = 0; | 537 | xprt->bind_index = 0; |
| 329 | status = -EPFNOSUPPORT; | 538 | status = -EPFNOSUPPORT; |
| 330 | dprintk("RPC: %5u %s: no more getport versions available\n", | 539 | dprintk("RPC: %5u %s: no more getport versions available\n", |
| 331 | task->tk_pid, __func__); | 540 | task->tk_pid, __func__); |
| 332 | goto bailout_nofree; | 541 | goto bailout_nofree; |
| 333 | } | 542 | } |
| 334 | bind_version = info[xprt->bind_index].rpc_vers; | ||
| 335 | 543 | ||
| 336 | dprintk("RPC: %5u %s: trying rpcbind version %u\n", | 544 | dprintk("RPC: %5u %s: trying rpcbind version %u\n", |
| 337 | task->tk_pid, __func__, bind_version); | 545 | task->tk_pid, __func__, bind_version); |
| 338 | 546 | ||
| 339 | rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot, | 547 | rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot, |
| 340 | bind_version, 0); | 548 | bind_version); |
| 341 | if (IS_ERR(rpcb_clnt)) { | 549 | if (IS_ERR(rpcb_clnt)) { |
| 342 | status = PTR_ERR(rpcb_clnt); | 550 | status = PTR_ERR(rpcb_clnt); |
| 343 | dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", | 551 | dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n", |
| @@ -360,26 +568,23 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 360 | map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); | 568 | map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); |
| 361 | map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); | 569 | map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); |
| 362 | map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ | 570 | map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ |
| 571 | map->r_status = -EIO; | ||
| 363 | 572 | ||
| 364 | child = rpcb_call_async(rpcb_clnt, map, xprt->bind_index); | 573 | child = rpcb_call_async(rpcb_clnt, map, proc); |
| 365 | rpc_release_client(rpcb_clnt); | 574 | rpc_release_client(rpcb_clnt); |
| 366 | if (IS_ERR(child)) { | 575 | if (IS_ERR(child)) { |
| 367 | status = -EIO; | 576 | /* rpcb_map_release() has freed the arguments */ |
| 368 | dprintk("RPC: %5u %s: rpc_run_task failed\n", | 577 | dprintk("RPC: %5u %s: rpc_run_task failed\n", |
| 369 | task->tk_pid, __func__); | 578 | task->tk_pid, __func__); |
| 370 | goto bailout; | 579 | return; |
| 371 | } | 580 | } |
| 372 | rpc_put_task(child); | 581 | rpc_put_task(child); |
| 373 | 582 | ||
| 374 | task->tk_xprt->stat.bind_count++; | 583 | task->tk_xprt->stat.bind_count++; |
| 375 | return; | 584 | return; |
| 376 | 585 | ||
| 377 | bailout: | ||
| 378 | kfree(map); | ||
| 379 | xprt_put(xprt); | ||
| 380 | bailout_nofree: | 586 | bailout_nofree: |
| 381 | rpcb_wake_rpcbind_waiters(xprt, status); | 587 | rpcb_wake_rpcbind_waiters(xprt, status); |
| 382 | bailout_nowake: | ||
| 383 | task->tk_status = status; | 588 | task->tk_status = status; |
| 384 | } | 589 | } |
| 385 | EXPORT_SYMBOL_GPL(rpcb_getport_async); | 590 | EXPORT_SYMBOL_GPL(rpcb_getport_async); |
| @@ -418,9 +623,13 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) | |||
| 418 | dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n", | 623 | dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n", |
| 419 | child->tk_pid, status, map->r_port); | 624 | child->tk_pid, status, map->r_port); |
| 420 | 625 | ||
| 421 | rpcb_wake_rpcbind_waiters(xprt, status); | 626 | map->r_status = status; |
| 422 | } | 627 | } |
| 423 | 628 | ||
| 629 | /* | ||
| 630 | * XDR functions for rpcbind | ||
| 631 | */ | ||
| 632 | |||
| 424 | static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p, | 633 | static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p, |
| 425 | struct rpcbind_args *rpcb) | 634 | struct rpcbind_args *rpcb) |
| 426 | { | 635 | { |
| @@ -439,7 +648,7 @@ static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p, | |||
| 439 | unsigned short *portp) | 648 | unsigned short *portp) |
| 440 | { | 649 | { |
| 441 | *portp = (unsigned short) ntohl(*p++); | 650 | *portp = (unsigned short) ntohl(*p++); |
| 442 | dprintk("RPC: rpcb_decode_getport result %u\n", | 651 | dprintk("RPC: rpcb_decode_getport result %u\n", |
| 443 | *portp); | 652 | *portp); |
| 444 | return 0; | 653 | return 0; |
| 445 | } | 654 | } |
| @@ -448,8 +657,8 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p, | |||
| 448 | unsigned int *boolp) | 657 | unsigned int *boolp) |
| 449 | { | 658 | { |
| 450 | *boolp = (unsigned int) ntohl(*p++); | 659 | *boolp = (unsigned int) ntohl(*p++); |
| 451 | dprintk("RPC: rpcb_decode_set result %u\n", | 660 | dprintk("RPC: rpcb_decode_set: call %s\n", |
| 452 | *boolp); | 661 | (*boolp ? "succeeded" : "failed")); |
| 453 | return 0; | 662 | return 0; |
| 454 | } | 663 | } |
| 455 | 664 | ||
| @@ -572,52 +781,60 @@ out_err: | |||
| 572 | static struct rpc_procinfo rpcb_procedures2[] = { | 781 | static struct rpc_procinfo rpcb_procedures2[] = { |
| 573 | PROC(SET, mapping, set), | 782 | PROC(SET, mapping, set), |
| 574 | PROC(UNSET, mapping, set), | 783 | PROC(UNSET, mapping, set), |
| 575 | PROC(GETADDR, mapping, getport), | 784 | PROC(GETPORT, mapping, getport), |
| 576 | }; | 785 | }; |
| 577 | 786 | ||
| 578 | static struct rpc_procinfo rpcb_procedures3[] = { | 787 | static struct rpc_procinfo rpcb_procedures3[] = { |
| 579 | PROC(SET, mapping, set), | 788 | PROC(SET, getaddr, set), |
| 580 | PROC(UNSET, mapping, set), | 789 | PROC(UNSET, getaddr, set), |
| 581 | PROC(GETADDR, getaddr, getaddr), | 790 | PROC(GETADDR, getaddr, getaddr), |
| 582 | }; | 791 | }; |
| 583 | 792 | ||
| 584 | static struct rpc_procinfo rpcb_procedures4[] = { | 793 | static struct rpc_procinfo rpcb_procedures4[] = { |
| 585 | PROC(SET, mapping, set), | 794 | PROC(SET, getaddr, set), |
| 586 | PROC(UNSET, mapping, set), | 795 | PROC(UNSET, getaddr, set), |
| 796 | PROC(GETADDR, getaddr, getaddr), | ||
| 587 | PROC(GETVERSADDR, getaddr, getaddr), | 797 | PROC(GETVERSADDR, getaddr, getaddr), |
| 588 | }; | 798 | }; |
| 589 | 799 | ||
| 590 | static struct rpcb_info rpcb_next_version[] = { | 800 | static struct rpcb_info rpcb_next_version[] = { |
| 591 | #ifdef CONFIG_SUNRPC_BIND34 | 801 | { |
| 592 | { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] }, | 802 | .rpc_vers = RPCBVERS_2, |
| 593 | { 3, &rpcb_procedures3[RPCBPROC_GETADDR] }, | 803 | .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT], |
| 594 | #endif | 804 | }, |
| 595 | { 2, &rpcb_procedures2[RPCBPROC_GETPORT] }, | 805 | { |
| 596 | { 0, NULL }, | 806 | .rpc_proc = NULL, |
| 807 | }, | ||
| 597 | }; | 808 | }; |
| 598 | 809 | ||
| 599 | static struct rpcb_info rpcb_next_version6[] = { | 810 | static struct rpcb_info rpcb_next_version6[] = { |
| 600 | #ifdef CONFIG_SUNRPC_BIND34 | 811 | { |
| 601 | { 4, &rpcb_procedures4[RPCBPROC_GETVERSADDR] }, | 812 | .rpc_vers = RPCBVERS_4, |
| 602 | { 3, &rpcb_procedures3[RPCBPROC_GETADDR] }, | 813 | .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR], |
| 603 | #endif | 814 | }, |
| 604 | { 0, NULL }, | 815 | { |
| 816 | .rpc_vers = RPCBVERS_3, | ||
| 817 | .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR], | ||
| 818 | }, | ||
| 819 | { | ||
| 820 | .rpc_proc = NULL, | ||
| 821 | }, | ||
| 605 | }; | 822 | }; |
| 606 | 823 | ||
| 607 | static struct rpc_version rpcb_version2 = { | 824 | static struct rpc_version rpcb_version2 = { |
| 608 | .number = 2, | 825 | .number = RPCBVERS_2, |
| 609 | .nrprocs = RPCB_HIGHPROC_2, | 826 | .nrprocs = RPCB_HIGHPROC_2, |
| 610 | .procs = rpcb_procedures2 | 827 | .procs = rpcb_procedures2 |
| 611 | }; | 828 | }; |
| 612 | 829 | ||
| 613 | static struct rpc_version rpcb_version3 = { | 830 | static struct rpc_version rpcb_version3 = { |
| 614 | .number = 3, | 831 | .number = RPCBVERS_3, |
| 615 | .nrprocs = RPCB_HIGHPROC_3, | 832 | .nrprocs = RPCB_HIGHPROC_3, |
| 616 | .procs = rpcb_procedures3 | 833 | .procs = rpcb_procedures3 |
| 617 | }; | 834 | }; |
| 618 | 835 | ||
| 619 | static struct rpc_version rpcb_version4 = { | 836 | static struct rpc_version rpcb_version4 = { |
| 620 | .number = 4, | 837 | .number = RPCBVERS_4, |
| 621 | .nrprocs = RPCB_HIGHPROC_4, | 838 | .nrprocs = RPCB_HIGHPROC_4, |
| 622 | .procs = rpcb_procedures4 | 839 | .procs = rpcb_procedures4 |
| 623 | }; | 840 | }; |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 6eab9bf94baf..385f427bedad 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
| @@ -576,9 +576,7 @@ EXPORT_SYMBOL_GPL(rpc_delay); | |||
| 576 | */ | 576 | */ |
| 577 | static void rpc_prepare_task(struct rpc_task *task) | 577 | static void rpc_prepare_task(struct rpc_task *task) |
| 578 | { | 578 | { |
| 579 | lock_kernel(); | ||
| 580 | task->tk_ops->rpc_call_prepare(task, task->tk_calldata); | 579 | task->tk_ops->rpc_call_prepare(task, task->tk_calldata); |
| 581 | unlock_kernel(); | ||
| 582 | } | 580 | } |
| 583 | 581 | ||
| 584 | /* | 582 | /* |
| @@ -588,9 +586,7 @@ void rpc_exit_task(struct rpc_task *task) | |||
| 588 | { | 586 | { |
| 589 | task->tk_action = NULL; | 587 | task->tk_action = NULL; |
| 590 | if (task->tk_ops->rpc_call_done != NULL) { | 588 | if (task->tk_ops->rpc_call_done != NULL) { |
| 591 | lock_kernel(); | ||
| 592 | task->tk_ops->rpc_call_done(task, task->tk_calldata); | 589 | task->tk_ops->rpc_call_done(task, task->tk_calldata); |
| 593 | unlock_kernel(); | ||
| 594 | if (task->tk_action != NULL) { | 590 | if (task->tk_action != NULL) { |
| 595 | WARN_ON(RPC_ASSASSINATED(task)); | 591 | WARN_ON(RPC_ASSASSINATED(task)); |
| 596 | /* Always release the RPC slot and buffer memory */ | 592 | /* Always release the RPC slot and buffer memory */ |
| @@ -602,11 +598,8 @@ EXPORT_SYMBOL_GPL(rpc_exit_task); | |||
| 602 | 598 | ||
| 603 | void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) | 599 | void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) |
| 604 | { | 600 | { |
| 605 | if (ops->rpc_release != NULL) { | 601 | if (ops->rpc_release != NULL) |
| 606 | lock_kernel(); | ||
| 607 | ops->rpc_release(calldata); | 602 | ops->rpc_release(calldata); |
| 608 | unlock_kernel(); | ||
| 609 | } | ||
| 610 | } | 603 | } |
| 611 | 604 | ||
| 612 | /* | 605 | /* |
| @@ -626,19 +619,15 @@ static void __rpc_execute(struct rpc_task *task) | |||
| 626 | /* | 619 | /* |
| 627 | * Execute any pending callback. | 620 | * Execute any pending callback. |
| 628 | */ | 621 | */ |
| 629 | if (RPC_DO_CALLBACK(task)) { | 622 | if (task->tk_callback) { |
| 630 | /* Define a callback save pointer */ | ||
| 631 | void (*save_callback)(struct rpc_task *); | 623 | void (*save_callback)(struct rpc_task *); |
| 632 | 624 | ||
| 633 | /* | 625 | /* |
| 634 | * If a callback exists, save it, reset it, | 626 | * We set tk_callback to NULL before calling it, |
| 635 | * call it. | 627 | * in case it sets the tk_callback field itself: |
| 636 | * The save is needed to stop from resetting | ||
| 637 | * another callback set within the callback handler | ||
| 638 | * - Dave | ||
| 639 | */ | 628 | */ |
| 640 | save_callback=task->tk_callback; | 629 | save_callback = task->tk_callback; |
| 641 | task->tk_callback=NULL; | 630 | task->tk_callback = NULL; |
| 642 | save_callback(task); | 631 | save_callback(task); |
| 643 | } | 632 | } |
| 644 | 633 | ||
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e1770f7ba0b3..99a52aabe332 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
| @@ -690,7 +690,7 @@ static void xprt_connect_status(struct rpc_task *task) | |||
| 690 | { | 690 | { |
| 691 | struct rpc_xprt *xprt = task->tk_xprt; | 691 | struct rpc_xprt *xprt = task->tk_xprt; |
| 692 | 692 | ||
| 693 | if (task->tk_status >= 0) { | 693 | if (task->tk_status == 0) { |
| 694 | xprt->stat.connect_count++; | 694 | xprt->stat.connect_count++; |
| 695 | xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start; | 695 | xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start; |
| 696 | dprintk("RPC: %5u xprt_connect_status: connection established\n", | 696 | dprintk("RPC: %5u xprt_connect_status: connection established\n", |
| @@ -699,12 +699,6 @@ static void xprt_connect_status(struct rpc_task *task) | |||
| 699 | } | 699 | } |
| 700 | 700 | ||
| 701 | switch (task->tk_status) { | 701 | switch (task->tk_status) { |
| 702 | case -ECONNREFUSED: | ||
| 703 | case -ECONNRESET: | ||
| 704 | dprintk("RPC: %5u xprt_connect_status: server %s refused " | ||
| 705 | "connection\n", task->tk_pid, | ||
| 706 | task->tk_client->cl_server); | ||
| 707 | break; | ||
| 708 | case -ENOTCONN: | 702 | case -ENOTCONN: |
| 709 | dprintk("RPC: %5u xprt_connect_status: connection broken\n", | 703 | dprintk("RPC: %5u xprt_connect_status: connection broken\n", |
| 710 | task->tk_pid); | 704 | task->tk_pid); |
| @@ -878,6 +872,7 @@ void xprt_transmit(struct rpc_task *task) | |||
| 878 | return; | 872 | return; |
| 879 | 873 | ||
| 880 | req->rq_connect_cookie = xprt->connect_cookie; | 874 | req->rq_connect_cookie = xprt->connect_cookie; |
| 875 | req->rq_xtime = jiffies; | ||
| 881 | status = xprt->ops->send_request(task); | 876 | status = xprt->ops->send_request(task); |
| 882 | if (status == 0) { | 877 | if (status == 0) { |
| 883 | dprintk("RPC: %5u xmit complete\n", task->tk_pid); | 878 | dprintk("RPC: %5u xmit complete\n", task->tk_pid); |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index ddbe981ab516..4486c59c3aca 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -579,7 +579,6 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
| 579 | req->rq_svec->iov_base, | 579 | req->rq_svec->iov_base, |
| 580 | req->rq_svec->iov_len); | 580 | req->rq_svec->iov_len); |
| 581 | 581 | ||
| 582 | req->rq_xtime = jiffies; | ||
| 583 | status = xs_sendpages(transport->sock, | 582 | status = xs_sendpages(transport->sock, |
| 584 | xs_addr(xprt), | 583 | xs_addr(xprt), |
| 585 | xprt->addrlen, xdr, | 584 | xprt->addrlen, xdr, |
| @@ -671,7 +670,6 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
| 671 | * to cope with writespace callbacks arriving _after_ we have | 670 | * to cope with writespace callbacks arriving _after_ we have |
| 672 | * called sendmsg(). */ | 671 | * called sendmsg(). */ |
| 673 | while (1) { | 672 | while (1) { |
| 674 | req->rq_xtime = jiffies; | ||
| 675 | status = xs_sendpages(transport->sock, | 673 | status = xs_sendpages(transport->sock, |
| 676 | NULL, 0, xdr, req->rq_bytes_sent); | 674 | NULL, 0, xdr, req->rq_bytes_sent); |
| 677 | 675 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 657835f227d3..783317dacd30 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -487,8 +487,8 @@ static int unix_socketpair(struct socket *, struct socket *); | |||
| 487 | static int unix_accept(struct socket *, struct socket *, int); | 487 | static int unix_accept(struct socket *, struct socket *, int); |
| 488 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); | 488 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); |
| 489 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); | 489 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); |
| 490 | static unsigned int unix_datagram_poll(struct file *, struct socket *, | 490 | static unsigned int unix_dgram_poll(struct file *, struct socket *, |
| 491 | poll_table *); | 491 | poll_table *); |
| 492 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); | 492 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); |
| 493 | static int unix_shutdown(struct socket *, int); | 493 | static int unix_shutdown(struct socket *, int); |
| 494 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, | 494 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, |
| @@ -534,7 +534,7 @@ static const struct proto_ops unix_dgram_ops = { | |||
| 534 | .socketpair = unix_socketpair, | 534 | .socketpair = unix_socketpair, |
| 535 | .accept = sock_no_accept, | 535 | .accept = sock_no_accept, |
| 536 | .getname = unix_getname, | 536 | .getname = unix_getname, |
| 537 | .poll = unix_datagram_poll, | 537 | .poll = unix_dgram_poll, |
| 538 | .ioctl = unix_ioctl, | 538 | .ioctl = unix_ioctl, |
| 539 | .listen = sock_no_listen, | 539 | .listen = sock_no_listen, |
| 540 | .shutdown = unix_shutdown, | 540 | .shutdown = unix_shutdown, |
| @@ -555,7 +555,7 @@ static const struct proto_ops unix_seqpacket_ops = { | |||
| 555 | .socketpair = unix_socketpair, | 555 | .socketpair = unix_socketpair, |
| 556 | .accept = unix_accept, | 556 | .accept = unix_accept, |
| 557 | .getname = unix_getname, | 557 | .getname = unix_getname, |
| 558 | .poll = unix_datagram_poll, | 558 | .poll = unix_dgram_poll, |
| 559 | .ioctl = unix_ioctl, | 559 | .ioctl = unix_ioctl, |
| 560 | .listen = unix_listen, | 560 | .listen = unix_listen, |
| 561 | .shutdown = unix_shutdown, | 561 | .shutdown = unix_shutdown, |
| @@ -1994,29 +1994,13 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl | |||
| 1994 | return mask; | 1994 | return mask; |
| 1995 | } | 1995 | } |
| 1996 | 1996 | ||
| 1997 | static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | 1997 | static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, |
| 1998 | poll_table *wait) | 1998 | poll_table *wait) |
| 1999 | { | 1999 | { |
| 2000 | struct sock *sk = sock->sk, *peer; | 2000 | struct sock *sk = sock->sk, *other; |
| 2001 | unsigned int mask; | 2001 | unsigned int mask, writable; |
| 2002 | 2002 | ||
| 2003 | poll_wait(file, sk->sk_sleep, wait); | 2003 | poll_wait(file, sk->sk_sleep, wait); |
| 2004 | |||
| 2005 | peer = unix_peer_get(sk); | ||
| 2006 | if (peer) { | ||
| 2007 | if (peer != sk) { | ||
| 2008 | /* | ||
| 2009 | * Writability of a connected socket additionally | ||
| 2010 | * depends on the state of the receive queue of the | ||
| 2011 | * peer. | ||
| 2012 | */ | ||
| 2013 | poll_wait(file, &unix_sk(peer)->peer_wait, wait); | ||
| 2014 | } else { | ||
| 2015 | sock_put(peer); | ||
| 2016 | peer = NULL; | ||
| 2017 | } | ||
| 2018 | } | ||
| 2019 | |||
| 2020 | mask = 0; | 2004 | mask = 0; |
| 2021 | 2005 | ||
| 2022 | /* exceptional events? */ | 2006 | /* exceptional events? */ |
| @@ -2042,14 +2026,26 @@ static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | |||
| 2042 | } | 2026 | } |
| 2043 | 2027 | ||
| 2044 | /* writable? */ | 2028 | /* writable? */ |
| 2045 | if (unix_writable(sk) && !(peer && unix_recvq_full(peer))) | 2029 | writable = unix_writable(sk); |
| 2030 | if (writable) { | ||
| 2031 | other = unix_peer_get(sk); | ||
| 2032 | if (other) { | ||
| 2033 | if (unix_peer(other) != sk) { | ||
| 2034 | poll_wait(file, &unix_sk(other)->peer_wait, | ||
| 2035 | wait); | ||
| 2036 | if (unix_recvq_full(other)) | ||
| 2037 | writable = 0; | ||
| 2038 | } | ||
| 2039 | |||
| 2040 | sock_put(other); | ||
| 2041 | } | ||
| 2042 | } | ||
| 2043 | |||
| 2044 | if (writable) | ||
| 2046 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | 2045 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; |
| 2047 | else | 2046 | else |
| 2048 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | 2047 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
| 2049 | 2048 | ||
| 2050 | if (peer) | ||
| 2051 | sock_put(peer); | ||
| 2052 | |||
| 2053 | return mask; | 2049 | return mask; |
| 2054 | } | 2050 | } |
| 2055 | 2051 | ||
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 185488da2466..855bff4b3250 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -80,6 +80,23 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = { | |||
| 80 | IEEE80211_CHAN_RADAR), | 80 | IEEE80211_CHAN_RADAR), |
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | static const struct ieee80211_channel_range ieee80211_EU_channels[] = { | ||
| 84 | /* IEEE 802.11b/g, channels 1..13 */ | ||
| 85 | RANGE_PWR(2412, 2472, 20, 6, 0), | ||
| 86 | /* IEEE 802.11a, channel 36*/ | ||
| 87 | RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
| 88 | /* IEEE 802.11a, channel 40*/ | ||
| 89 | RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
| 90 | /* IEEE 802.11a, channel 44*/ | ||
| 91 | RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
| 92 | /* IEEE 802.11a, channels 48..64 */ | ||
| 93 | RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS | | ||
| 94 | IEEE80211_CHAN_RADAR), | ||
| 95 | /* IEEE 802.11a, channels 100..140 */ | ||
| 96 | RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS | | ||
| 97 | IEEE80211_CHAN_RADAR), | ||
| 98 | }; | ||
| 99 | |||
| 83 | #define REGDOM(_code) \ | 100 | #define REGDOM(_code) \ |
| 84 | { \ | 101 | { \ |
| 85 | .code = __stringify(_code), \ | 102 | .code = __stringify(_code), \ |
| @@ -90,6 +107,7 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = { | |||
| 90 | static const struct ieee80211_regdomain ieee80211_regdoms[] = { | 107 | static const struct ieee80211_regdomain ieee80211_regdoms[] = { |
| 91 | REGDOM(US), | 108 | REGDOM(US), |
| 92 | REGDOM(JP), | 109 | REGDOM(JP), |
| 110 | REGDOM(EU), | ||
| 93 | }; | 111 | }; |
| 94 | 112 | ||
| 95 | 113 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index b976d9ed10e4..04c41504f84c 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -277,9 +277,8 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info * | |||
| 277 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); | 277 | memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr)); |
| 278 | x->props.flags = p->flags; | 278 | x->props.flags = p->flags; |
| 279 | 279 | ||
| 280 | if (!x->sel.family) | 280 | if (!x->sel.family && !(p->flags & XFRM_STATE_AF_UNSPEC)) |
| 281 | x->sel.family = p->family; | 281 | x->sel.family = p->family; |
| 282 | |||
| 283 | } | 282 | } |
| 284 | 283 | ||
| 285 | /* | 284 | /* |
