diff options
author | David S. Miller <davem@davemloft.net> | 2008-07-18 05:39:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-18 05:39:39 -0400 |
commit | 49997d75152b3d23c53b0fa730599f2f74c92c65 (patch) | |
tree | 46e93126170d02cfec9505172e545732c1b69656 /net | |
parent | a0c80b80e0fb48129e4e9d6a9ede914f9ff1850d (diff) | |
parent | 5b664cb235e97afbf34db9c4d77f08ebd725335e (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
Documentation/powerpc/booting-without-of.txt
drivers/atm/Makefile
drivers/net/fs_enet/fs_enet-main.c
drivers/pci/pci-acpi.c
net/8021q/vlan.c
net/iucv/iucv.c
Diffstat (limited to 'net')
-rw-r--r-- | net/802/psnap.c | 1 | ||||
-rw-r--r-- | net/8021q/vlan.c | 3 | ||||
-rw-r--r-- | net/bridge/br_fdb.c | 1 | ||||
-rw-r--r-- | net/bridge/br_stp.c | 1 | ||||
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/core/flow.c | 2 | ||||
-rw-r--r-- | net/irda/irnet/irnet.h | 1 | ||||
-rw-r--r-- | net/irda/irnet/irnet_ppp.c | 3 | ||||
-rw-r--r-- | net/iucv/af_iucv.c | 8 | ||||
-rw-r--r-- | net/iucv/iucv.c | 30 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 1 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 1 | ||||
-rw-r--r-- | net/netlabel/netlabel_domainhash.c | 3 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 27 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_krb5_mech.c | 4 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_mech.c | 4 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/gss_spkm3_token.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 12 | ||||
-rw-r--r-- | net/sunrpc/auth_unix.c | 2 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 161 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 377 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 23 | ||||
-rw-r--r-- | net/sunrpc/xprt.c | 9 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 2 |
24 files changed, 450 insertions, 232 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 9f04cab92f95..b661f47bf10a 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
24 | #include <linux/skbuff.h> | 24 | #include <linux/skbuff.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/rculist.h> | ||
27 | #include <net/p8022.h> | ||
28 | #include <net/arp.h> | ||
26 | #include <linux/rtnetlink.h> | 29 | #include <linux/rtnetlink.h> |
27 | #include <linux/notifier.h> | 30 | #include <linux/notifier.h> |
28 | #include <net/rtnetlink.h> | 31 | #include <net/rtnetlink.h> |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 4de74cdd091d..a48f5efdb6bf 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/rculist.h> | ||
16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
17 | #include <linux/times.h> | 18 | #include <linux/times.h> |
18 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 284d1b2fa1ff..921bbe5cb94a 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * 2 of the License, or (at your option) any later version. | 11 | * 2 of the License, or (at your option) any later version. |
12 | */ | 12 | */ |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/rculist.h> | ||
14 | 15 | ||
15 | #include "br_private.h" | 16 | #include "br_private.h" |
16 | #include "br_private_stp.h" | 17 | #include "br_private_stp.h" |
diff --git a/net/core/dev.c b/net/core/dev.c index 32a13772c1cb..e54acde839da 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -4775,8 +4775,8 @@ static int __init net_dev_init(void) | |||
4775 | 4775 | ||
4776 | dev_boot_phase = 0; | 4776 | dev_boot_phase = 0; |
4777 | 4777 | ||
4778 | open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); | 4778 | open_softirq(NET_TX_SOFTIRQ, net_tx_action); |
4779 | open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); | 4779 | open_softirq(NET_RX_SOFTIRQ, net_rx_action); |
4780 | 4780 | ||
4781 | hotcpu_notifier(dev_cpu_callback, 0); | 4781 | hotcpu_notifier(dev_cpu_callback, 0); |
4782 | dst_init(); | 4782 | dst_init(); |
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/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 f6e54fa97f47..6d8ae03c14f5 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/iucv/af_iucv.c b/net/iucv/af_iucv.c index 58e4aee3e696..29f7baa25110 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1136,8 +1136,7 @@ static void iucv_callback_txdone(struct iucv_path *path, | |||
1136 | if (this) | 1136 | if (this) |
1137 | kfree_skb(this); | 1137 | kfree_skb(this); |
1138 | } | 1138 | } |
1139 | if (!this) | 1139 | BUG_ON(!this); |
1140 | printk(KERN_ERR "AF_IUCV msg tag %u not found\n", msg->tag); | ||
1141 | 1140 | ||
1142 | if (sk->sk_state == IUCV_CLOSING) { | 1141 | if (sk->sk_state == IUCV_CLOSING) { |
1143 | if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) { | 1142 | if (skb_queue_empty(&iucv_sk(sk)->send_skb_q)) { |
@@ -1197,7 +1196,7 @@ static int __init afiucv_init(void) | |||
1197 | } | 1196 | } |
1198 | cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err); | 1197 | cpcmd("QUERY USERID", iucv_userid, sizeof(iucv_userid), &err); |
1199 | if (unlikely(err)) { | 1198 | if (unlikely(err)) { |
1200 | printk(KERN_ERR "AF_IUCV needs the VM userid\n"); | 1199 | WARN_ON(err); |
1201 | err = -EPROTONOSUPPORT; | 1200 | err = -EPROTONOSUPPORT; |
1202 | goto out; | 1201 | goto out; |
1203 | } | 1202 | } |
@@ -1211,7 +1210,6 @@ static int __init afiucv_init(void) | |||
1211 | err = sock_register(&iucv_sock_family_ops); | 1210 | err = sock_register(&iucv_sock_family_ops); |
1212 | if (err) | 1211 | if (err) |
1213 | goto out_proto; | 1212 | goto out_proto; |
1214 | printk(KERN_INFO "AF_IUCV lowlevel driver initialized\n"); | ||
1215 | return 0; | 1213 | return 0; |
1216 | 1214 | ||
1217 | out_proto: | 1215 | out_proto: |
@@ -1227,8 +1225,6 @@ static void __exit afiucv_exit(void) | |||
1227 | sock_unregister(PF_IUCV); | 1225 | sock_unregister(PF_IUCV); |
1228 | proto_unregister(&iucv_proto); | 1226 | proto_unregister(&iucv_proto); |
1229 | iucv_unregister(&af_iucv_handler, 0); | 1227 | iucv_unregister(&af_iucv_handler, 0); |
1230 | |||
1231 | printk(KERN_INFO "AF_IUCV lowlevel driver unloaded\n"); | ||
1232 | } | 1228 | } |
1233 | 1229 | ||
1234 | module_init(afiucv_init); | 1230 | module_init(afiucv_init); |
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index d8e0635aace0..a598c7384840 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 | put_online_cpus(); | 484 | put_online_cpus(); |
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,12 @@ static int iucv_enable(void) | |||
523 | rc = -EIO; | 523 | rc = -EIO; |
524 | get_online_cpus(); | 524 | get_online_cpus(); |
525 | for_each_online_cpu(cpu) | 525 | for_each_online_cpu(cpu) |
526 | <<<<<<< HEAD:net/iucv/iucv.c | ||
526 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1); | 527 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1); |
528 | ======= | ||
529 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1); | ||
530 | preempt_enable(); | ||
531 | >>>>>>> 5b664cb235e97afbf34db9c4d77f08ebd725335e:net/iucv/iucv.c | ||
527 | if (cpus_empty(iucv_buffer_cpumask)) | 532 | if (cpus_empty(iucv_buffer_cpumask)) |
528 | /* No cpu could declare an iucv buffer. */ | 533 | /* No cpu could declare an iucv buffer. */ |
529 | goto out_path; | 534 | goto out_path; |
@@ -546,9 +551,13 @@ out: | |||
546 | */ | 551 | */ |
547 | static void iucv_disable(void) | 552 | static void iucv_disable(void) |
548 | { | 553 | { |
554 | <<<<<<< HEAD:net/iucv/iucv.c | ||
549 | get_online_cpus(); | 555 | get_online_cpus(); |
550 | on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1); | 556 | on_each_cpu(iucv_retrieve_cpu, NULL, 0, 1); |
551 | put_online_cpus(); | 557 | put_online_cpus(); |
558 | ======= | ||
559 | on_each_cpu(iucv_retrieve_cpu, NULL, 1); | ||
560 | >>>>>>> 5b664cb235e97afbf34db9c4d77f08ebd725335e:net/iucv/iucv.c | ||
552 | kfree(iucv_path_table); | 561 | kfree(iucv_path_table); |
553 | } | 562 | } |
554 | 563 | ||
@@ -586,7 +595,7 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
586 | case CPU_ONLINE_FROZEN: | 595 | case CPU_ONLINE_FROZEN: |
587 | case CPU_DOWN_FAILED: | 596 | case CPU_DOWN_FAILED: |
588 | case CPU_DOWN_FAILED_FROZEN: | 597 | case CPU_DOWN_FAILED_FROZEN: |
589 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 0, 1); | 598 | smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1); |
590 | break; | 599 | break; |
591 | case CPU_DOWN_PREPARE: | 600 | case CPU_DOWN_PREPARE: |
592 | case CPU_DOWN_PREPARE_FROZEN: | 601 | case CPU_DOWN_PREPARE_FROZEN: |
@@ -595,10 +604,10 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self, | |||
595 | if (cpus_empty(cpumask)) | 604 | if (cpus_empty(cpumask)) |
596 | /* Can't offline last IUCV enabled cpu. */ | 605 | /* Can't offline last IUCV enabled cpu. */ |
597 | return NOTIFY_BAD; | 606 | return NOTIFY_BAD; |
598 | smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 0, 1); | 607 | smp_call_function_single(cpu, iucv_retrieve_cpu, NULL, 1); |
599 | if (cpus_empty(iucv_irq_cpumask)) | 608 | if (cpus_empty(iucv_irq_cpumask)) |
600 | smp_call_function_single(first_cpu(iucv_buffer_cpumask), | 609 | smp_call_function_single(first_cpu(iucv_buffer_cpumask), |
601 | iucv_allow_cpu, NULL, 0, 1); | 610 | iucv_allow_cpu, NULL, 1); |
602 | break; | 611 | break; |
603 | } | 612 | } |
604 | return NOTIFY_OK; | 613 | return NOTIFY_OK; |
@@ -658,7 +667,7 @@ static void iucv_cleanup_queue(void) | |||
658 | * pending interrupts force them to the work queue by calling | 667 | * pending interrupts force them to the work queue by calling |
659 | * an empty function on all cpus. | 668 | * an empty function on all cpus. |
660 | */ | 669 | */ |
661 | smp_call_function(__iucv_cleanup_queue, NULL, 0, 1); | 670 | smp_call_function(__iucv_cleanup_queue, NULL, 1); |
662 | spin_lock_irq(&iucv_queue_lock); | 671 | spin_lock_irq(&iucv_queue_lock); |
663 | list_for_each_entry_safe(p, n, &iucv_task_queue, list) { | 672 | list_for_each_entry_safe(p, n, &iucv_task_queue, list) { |
664 | /* Remove stale work items from the task queue. */ | 673 | /* Remove stale work items from the task queue. */ |
@@ -1565,16 +1574,11 @@ static void iucv_external_interrupt(u16 code) | |||
1565 | 1574 | ||
1566 | p = iucv_irq_data[smp_processor_id()]; | 1575 | p = iucv_irq_data[smp_processor_id()]; |
1567 | if (p->ippathid >= iucv_max_pathid) { | 1576 | if (p->ippathid >= iucv_max_pathid) { |
1568 | printk(KERN_WARNING "iucv_do_int: Got interrupt with " | 1577 | WARN_ON(p->ippathid >= iucv_max_pathid); |
1569 | "pathid %d > max_connections (%ld)\n", | ||
1570 | p->ippathid, iucv_max_pathid - 1); | ||
1571 | iucv_sever_pathid(p->ippathid, iucv_error_no_listener); | 1578 | iucv_sever_pathid(p->ippathid, iucv_error_no_listener); |
1572 | return; | 1579 | return; |
1573 | } | 1580 | } |
1574 | if (p->iptype < 0x01 || p->iptype > 0x09) { | 1581 | BUG_ON(p->iptype < 0x01 || p->iptype > 0x09); |
1575 | printk(KERN_ERR "iucv_do_int: unknown iucv interrupt\n"); | ||
1576 | return; | ||
1577 | } | ||
1578 | work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); | 1582 | work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); |
1579 | if (!work) { | 1583 | if (!work) { |
1580 | printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); | 1584 | printk(KERN_WARNING "iucv_external_interrupt: out of memory\n"); |
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 dd233393f695..95a7967731f9 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/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/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 019d4b4478c9..853a4142cea1 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -61,22 +61,11 @@ static const struct rpc_credops gss_nullops; | |||
61 | # define RPCDBG_FACILITY RPCDBG_AUTH | 61 | # define RPCDBG_FACILITY RPCDBG_AUTH |
62 | #endif | 62 | #endif |
63 | 63 | ||
64 | #define NFS_NGROUPS 16 | 64 | #define GSS_CRED_SLACK 1024 |
65 | |||
66 | #define GSS_CRED_SLACK 1024 /* XXX: unused */ | ||
67 | /* length of a krb5 verifier (48), plus data added before arguments when | 65 | /* length of a krb5 verifier (48), plus data added before arguments when |
68 | * using integrity (two 4-byte integers): */ | 66 | * using integrity (two 4-byte integers): */ |
69 | #define GSS_VERF_SLACK 100 | 67 | #define GSS_VERF_SLACK 100 |
70 | 68 | ||
71 | /* XXX this define must match the gssd define | ||
72 | * as it is passed to gssd to signal the use of | ||
73 | * machine creds should be part of the shared rpc interface */ | ||
74 | |||
75 | #define CA_RUN_AS_MACHINE 0x00000200 | ||
76 | |||
77 | /* dump the buffer in `emacs-hexl' style */ | ||
78 | #define isprint(c) ((c > 0x1f) && (c < 0x7f)) | ||
79 | |||
80 | struct gss_auth { | 69 | struct gss_auth { |
81 | struct kref kref; | 70 | struct kref kref; |
82 | struct rpc_auth rpc_auth; | 71 | struct rpc_auth rpc_auth; |
@@ -144,7 +133,7 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) | |||
144 | q = (const void *)((const char *)p + len); | 133 | q = (const void *)((const char *)p + len); |
145 | if (unlikely(q > end || q < p)) | 134 | if (unlikely(q > end || q < p)) |
146 | return ERR_PTR(-EFAULT); | 135 | return ERR_PTR(-EFAULT); |
147 | dest->data = kmemdup(p, len, GFP_KERNEL); | 136 | dest->data = kmemdup(p, len, GFP_NOFS); |
148 | if (unlikely(dest->data == NULL)) | 137 | if (unlikely(dest->data == NULL)) |
149 | return ERR_PTR(-ENOMEM); | 138 | return ERR_PTR(-ENOMEM); |
150 | dest->len = len; | 139 | dest->len = len; |
@@ -169,7 +158,7 @@ gss_alloc_context(void) | |||
169 | { | 158 | { |
170 | struct gss_cl_ctx *ctx; | 159 | struct gss_cl_ctx *ctx; |
171 | 160 | ||
172 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 161 | ctx = kzalloc(sizeof(*ctx), GFP_NOFS); |
173 | if (ctx != NULL) { | 162 | if (ctx != NULL) { |
174 | ctx->gc_proc = RPC_GSS_PROC_DATA; | 163 | ctx->gc_proc = RPC_GSS_PROC_DATA; |
175 | ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ | 164 | ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ |
@@ -270,7 +259,7 @@ __gss_find_upcall(struct rpc_inode *rpci, uid_t uid) | |||
270 | return NULL; | 259 | return NULL; |
271 | } | 260 | } |
272 | 261 | ||
273 | /* Try to add a upcall to the pipefs queue. | 262 | /* Try to add an upcall to the pipefs queue. |
274 | * If an upcall owned by our uid already exists, then we return a reference | 263 | * If an upcall owned by our uid already exists, then we return a reference |
275 | * to that upcall instead of adding the new upcall. | 264 | * to that upcall instead of adding the new upcall. |
276 | */ | 265 | */ |
@@ -339,7 +328,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) | |||
339 | { | 328 | { |
340 | struct gss_upcall_msg *gss_msg; | 329 | struct gss_upcall_msg *gss_msg; |
341 | 330 | ||
342 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL); | 331 | gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); |
343 | if (gss_msg != NULL) { | 332 | if (gss_msg != NULL) { |
344 | INIT_LIST_HEAD(&gss_msg->list); | 333 | INIT_LIST_HEAD(&gss_msg->list); |
345 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); | 334 | rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); |
@@ -491,7 +480,6 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
491 | { | 480 | { |
492 | const void *p, *end; | 481 | const void *p, *end; |
493 | void *buf; | 482 | void *buf; |
494 | struct rpc_clnt *clnt; | ||
495 | struct gss_upcall_msg *gss_msg; | 483 | struct gss_upcall_msg *gss_msg; |
496 | struct inode *inode = filp->f_path.dentry->d_inode; | 484 | struct inode *inode = filp->f_path.dentry->d_inode; |
497 | struct gss_cl_ctx *ctx; | 485 | struct gss_cl_ctx *ctx; |
@@ -501,11 +489,10 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
501 | if (mlen > MSG_BUF_MAXSIZE) | 489 | if (mlen > MSG_BUF_MAXSIZE) |
502 | goto out; | 490 | goto out; |
503 | err = -ENOMEM; | 491 | err = -ENOMEM; |
504 | buf = kmalloc(mlen, GFP_KERNEL); | 492 | buf = kmalloc(mlen, GFP_NOFS); |
505 | if (!buf) | 493 | if (!buf) |
506 | goto out; | 494 | goto out; |
507 | 495 | ||
508 | clnt = RPC_I(inode)->private; | ||
509 | err = -EFAULT; | 496 | err = -EFAULT; |
510 | if (copy_from_user(buf, src, mlen)) | 497 | if (copy_from_user(buf, src, mlen)) |
511 | goto err; | 498 | goto err; |
@@ -804,7 +791,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
804 | dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", | 791 | dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", |
805 | acred->uid, auth->au_flavor); | 792 | acred->uid, auth->au_flavor); |
806 | 793 | ||
807 | if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) | 794 | if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) |
808 | goto out_err; | 795 | goto out_err; |
809 | 796 | ||
810 | rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); | 797 | 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 | ||