aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-08-10 07:22:08 -0400
committerJiri Kosina <jkosina@suse.cz>2010-08-10 07:22:08 -0400
commitfb8231a8b139035476f2a8aaac837d0099b66dad (patch)
tree2875806beb96ea0cdab292146767a5085721dc6a /net
parent426d31071ac476ea62c62656b242930c17b58c00 (diff)
parentf6cec0ae58c17522a7bc4e2f39dae19f199ab534 (diff)
Merge branch 'master' into for-next
Conflicts: arch/arm/mach-omap1/board-nokia770.c
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig1
-rw-r--r--net/Makefile1
-rw-r--r--net/atm/pppoatm.c2
-rw-r--r--net/bluetooth/hci_core.c2
-rw-r--r--net/bluetooth/hci_sock.c8
-rw-r--r--net/bluetooth/hci_sysfs.c3
-rw-r--r--net/bluetooth/l2cap.c24
-rw-r--r--net/bluetooth/rfcomm/tty.c2
-rw-r--r--net/core/dev.c7
-rw-r--r--net/dns_resolver/Kconfig27
-rw-r--r--net/dns_resolver/Makefile7
-rw-r--r--net/dns_resolver/dns_key.c211
-rw-r--r--net/dns_resolver/dns_query.c160
-rw-r--r--net/dns_resolver/internal.h44
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/irda/irnet/irnet_ppp.c2
-rw-r--r--net/l2tp/l2tp_ppp.c5
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/scan.c14
-rw-r--r--net/rxrpc/ar-ack.c3
-rw-r--r--net/rxrpc/ar-call.c6
-rw-r--r--net/sched/act_nat.c23
-rw-r--r--net/sched/cls_flow.c96
-rw-r--r--net/sched/cls_rsvp.h12
-rw-r--r--net/sched/sch_sfq.c36
-rw-r--r--net/sunrpc/auth.c157
-rw-r--r--net/sunrpc/auth_generic.c23
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c29
-rw-r--r--net/sunrpc/auth_null.c2
-rw-r--r--net/sunrpc/auth_unix.c21
-rw-r--r--net/sunrpc/cache.c8
-rw-r--r--net/sunrpc/clnt.c182
-rw-r--r--net/sunrpc/sched.c104
-rw-r--r--net/sunrpc/sunrpc_syms.c16
-rw-r--r--net/sunrpc/xprt.c3
35 files changed, 909 insertions, 336 deletions
diff --git a/net/Kconfig b/net/Kconfig
index e24fa0873f32..e330594d3709 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -213,6 +213,7 @@ source "net/phonet/Kconfig"
213source "net/ieee802154/Kconfig" 213source "net/ieee802154/Kconfig"
214source "net/sched/Kconfig" 214source "net/sched/Kconfig"
215source "net/dcb/Kconfig" 215source "net/dcb/Kconfig"
216source "net/dns_resolver/Kconfig"
216 217
217config RPS 218config RPS
218 boolean 219 boolean
diff --git a/net/Makefile b/net/Makefile
index 41d420070a38..ea60fbce9b1b 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -67,3 +67,4 @@ ifeq ($(CONFIG_NET),y)
67obj-$(CONFIG_SYSCTL) += sysctl_net.o 67obj-$(CONFIG_SYSCTL) += sysctl_net.o
68endif 68endif
69obj-$(CONFIG_WIMAX) += wimax/ 69obj-$(CONFIG_WIMAX) += wimax/
70obj-$(CONFIG_DNS_RESOLVER) += dns_resolver/
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index e49bb6d948a1..e9aced0ec56b 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -260,7 +260,7 @@ static int pppoatm_devppp_ioctl(struct ppp_channel *chan, unsigned int cmd,
260 return -ENOTTY; 260 return -ENOTTY;
261} 261}
262 262
263static /*const*/ struct ppp_channel_ops pppoatm_ops = { 263static const struct ppp_channel_ops pppoatm_ops = {
264 .start_xmit = pppoatm_send, 264 .start_xmit = pppoatm_send,
265 .ioctl = pppoatm_devppp_ioctl, 265 .ioctl = pppoatm_devppp_ioctl,
266}; 266};
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8303f1c9ef54..c52f091ee6de 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -924,7 +924,7 @@ int hci_register_dev(struct hci_dev *hdev)
924 924
925 hci_conn_hash_init(hdev); 925 hci_conn_hash_init(hdev);
926 926
927 INIT_LIST_HEAD(&hdev->blacklist.list); 927 INIT_LIST_HEAD(&hdev->blacklist);
928 928
929 memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); 929 memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
930 930
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 4f170a595934..83acd164d39e 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -168,9 +168,8 @@ static int hci_sock_release(struct socket *sock)
168struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) 168struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
169{ 169{
170 struct list_head *p; 170 struct list_head *p;
171 struct bdaddr_list *blacklist = &hdev->blacklist;
172 171
173 list_for_each(p, &blacklist->list) { 172 list_for_each(p, &hdev->blacklist) {
174 struct bdaddr_list *b; 173 struct bdaddr_list *b;
175 174
176 b = list_entry(p, struct bdaddr_list, list); 175 b = list_entry(p, struct bdaddr_list, list);
@@ -202,7 +201,7 @@ static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg)
202 201
203 bacpy(&entry->bdaddr, &bdaddr); 202 bacpy(&entry->bdaddr, &bdaddr);
204 203
205 list_add(&entry->list, &hdev->blacklist.list); 204 list_add(&entry->list, &hdev->blacklist);
206 205
207 return 0; 206 return 0;
208} 207}
@@ -210,9 +209,8 @@ static int hci_blacklist_add(struct hci_dev *hdev, void __user *arg)
210int hci_blacklist_clear(struct hci_dev *hdev) 209int hci_blacklist_clear(struct hci_dev *hdev)
211{ 210{
212 struct list_head *p, *n; 211 struct list_head *p, *n;
213 struct bdaddr_list *blacklist = &hdev->blacklist;
214 212
215 list_for_each_safe(p, n, &blacklist->list) { 213 list_for_each_safe(p, n, &hdev->blacklist) {
216 struct bdaddr_list *b; 214 struct bdaddr_list *b;
217 215
218 b = list_entry(p, struct bdaddr_list, list); 216 b = list_entry(p, struct bdaddr_list, list);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index ce44c47eeac1..8fb967beee80 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -439,12 +439,11 @@ static const struct file_operations inquiry_cache_fops = {
439static int blacklist_show(struct seq_file *f, void *p) 439static int blacklist_show(struct seq_file *f, void *p)
440{ 440{
441 struct hci_dev *hdev = f->private; 441 struct hci_dev *hdev = f->private;
442 struct bdaddr_list *blacklist = &hdev->blacklist;
443 struct list_head *l; 442 struct list_head *l;
444 443
445 hci_dev_lock_bh(hdev); 444 hci_dev_lock_bh(hdev);
446 445
447 list_for_each(l, &blacklist->list) { 446 list_for_each(l, &hdev->blacklist) {
448 struct bdaddr_list *b; 447 struct bdaddr_list *b;
449 bdaddr_t bdaddr; 448 bdaddr_t bdaddr;
450 449
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 9ba1e8eee37c..3e3cd9d4e52c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2527,6 +2527,10 @@ done:
2527 if (pi->imtu != L2CAP_DEFAULT_MTU) 2527 if (pi->imtu != L2CAP_DEFAULT_MTU)
2528 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); 2528 l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
2529 2529
2530 if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) &&
2531 !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING))
2532 break;
2533
2530 rfc.mode = L2CAP_MODE_BASIC; 2534 rfc.mode = L2CAP_MODE_BASIC;
2531 rfc.txwin_size = 0; 2535 rfc.txwin_size = 0;
2532 rfc.max_transmit = 0; 2536 rfc.max_transmit = 0;
@@ -2534,6 +2538,8 @@ done:
2534 rfc.monitor_timeout = 0; 2538 rfc.monitor_timeout = 0;
2535 rfc.max_pdu_size = 0; 2539 rfc.max_pdu_size = 0;
2536 2540
2541 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2542 (unsigned long) &rfc);
2537 break; 2543 break;
2538 2544
2539 case L2CAP_MODE_ERTM: 2545 case L2CAP_MODE_ERTM:
@@ -2546,6 +2552,9 @@ done:
2546 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) 2552 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2547 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); 2553 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
2548 2554
2555 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2556 (unsigned long) &rfc);
2557
2549 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) 2558 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2550 break; 2559 break;
2551 2560
@@ -2566,6 +2575,9 @@ done:
2566 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10) 2575 if (L2CAP_DEFAULT_MAX_PDU_SIZE > pi->conn->mtu - 10)
2567 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); 2576 rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10);
2568 2577
2578 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2579 (unsigned long) &rfc);
2580
2569 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS)) 2581 if (!(pi->conn->feat_mask & L2CAP_FEAT_FCS))
2570 break; 2582 break;
2571 2583
@@ -2577,9 +2589,6 @@ done:
2577 break; 2589 break;
2578 } 2590 }
2579 2591
2580 l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
2581 (unsigned long) &rfc);
2582
2583 /* FIXME: Need actual value of the flush timeout */ 2592 /* FIXME: Need actual value of the flush timeout */
2584 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) 2593 //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
2585 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); 2594 // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
@@ -3339,6 +3348,15 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
3339 3348
3340 del_timer(&conn->info_timer); 3349 del_timer(&conn->info_timer);
3341 3350
3351 if (result != L2CAP_IR_SUCCESS) {
3352 conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
3353 conn->info_ident = 0;
3354
3355 l2cap_conn_start(conn);
3356
3357 return 0;
3358 }
3359
3342 if (type == L2CAP_IT_FEAT_MASK) { 3360 if (type == L2CAP_IT_FEAT_MASK) {
3343 conn->feat_mask = get_unaligned_le32(rsp->data); 3361 conn->feat_mask = get_unaligned_le32(rsp->data);
3344 3362
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 026205c18b78..befc3a52aa04 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -1183,7 +1183,7 @@ int __init rfcomm_init_ttys(void)
1183 return 0; 1183 return 0;
1184} 1184}
1185 1185
1186void __exit rfcomm_cleanup_ttys(void) 1186void rfcomm_cleanup_ttys(void)
1187{ 1187{
1188 tty_unregister_driver(rfcomm_tty_driver); 1188 tty_unregister_driver(rfcomm_tty_driver);
1189 put_tty_driver(rfcomm_tty_driver); 1189 put_tty_driver(rfcomm_tty_driver);
diff --git a/net/core/dev.c b/net/core/dev.c
index e1c1cdcc2bb0..1ae654391442 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2517,6 +2517,7 @@ int netif_rx(struct sk_buff *skb)
2517 struct rps_dev_flow voidflow, *rflow = &voidflow; 2517 struct rps_dev_flow voidflow, *rflow = &voidflow;
2518 int cpu; 2518 int cpu;
2519 2519
2520 preempt_disable();
2520 rcu_read_lock(); 2521 rcu_read_lock();
2521 2522
2522 cpu = get_rps_cpu(skb->dev, skb, &rflow); 2523 cpu = get_rps_cpu(skb->dev, skb, &rflow);
@@ -2526,6 +2527,7 @@ int netif_rx(struct sk_buff *skb)
2526 ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); 2527 ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
2527 2528
2528 rcu_read_unlock(); 2529 rcu_read_unlock();
2530 preempt_enable();
2529 } 2531 }
2530#else 2532#else
2531 { 2533 {
@@ -3072,7 +3074,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
3072 int mac_len; 3074 int mac_len;
3073 enum gro_result ret; 3075 enum gro_result ret;
3074 3076
3075 if (!(skb->dev->features & NETIF_F_GRO)) 3077 if (!(skb->dev->features & NETIF_F_GRO) || netpoll_rx_on(skb))
3076 goto normal; 3078 goto normal;
3077 3079
3078 if (skb_is_gso(skb) || skb_has_frags(skb)) 3080 if (skb_is_gso(skb) || skb_has_frags(skb))
@@ -3159,9 +3161,6 @@ __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
3159{ 3161{
3160 struct sk_buff *p; 3162 struct sk_buff *p;
3161 3163
3162 if (netpoll_rx_on(skb))
3163 return GRO_NORMAL;
3164
3165 for (p = napi->gro_list; p; p = p->next) { 3164 for (p = napi->gro_list; p; p = p->next) {
3166 NAPI_GRO_CB(p)->same_flow = 3165 NAPI_GRO_CB(p)->same_flow =
3167 (p->dev == skb->dev) && 3166 (p->dev == skb->dev) &&
diff --git a/net/dns_resolver/Kconfig b/net/dns_resolver/Kconfig
new file mode 100644
index 000000000000..50d49f7e0472
--- /dev/null
+++ b/net/dns_resolver/Kconfig
@@ -0,0 +1,27 @@
1#
2# Configuration for DNS Resolver
3#
4config DNS_RESOLVER
5 tristate "DNS Resolver support"
6 depends on NET && KEYS
7 help
8 Saying Y here will include support for the DNS Resolver key type
9 which can be used to make upcalls to perform DNS lookups in
10 userspace.
11
12 DNS Resolver is used to query DNS server for information. Examples
13 being resolving a UNC hostname element to an IP address for CIFS or
14 performing a DNS query for AFSDB records so that AFS can locate a
15 cell's volume location database servers.
16
17 DNS Resolver is used by the CIFS and AFS modules, and would support
18 SMB2 later. DNS Resolver is supported by the userspace upcall
19 helper "/sbin/dns.resolver" via /etc/request-key.conf.
20
21 See <file:Documentation/networking/dns_resolver.txt> for further
22 information.
23
24 To compile this as a module, choose M here: the module will be called
25 dnsresolver.
26
27 If unsure, say N.
diff --git a/net/dns_resolver/Makefile b/net/dns_resolver/Makefile
new file mode 100644
index 000000000000..c0ef4e71dc49
--- /dev/null
+++ b/net/dns_resolver/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the Linux DNS Resolver.
3#
4
5obj-$(CONFIG_DNS_RESOLVER) += dns_resolver.o
6
7dns_resolver-objs := dns_key.o dns_query.o
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
new file mode 100644
index 000000000000..400a04d5c9a1
--- /dev/null
+++ b/net/dns_resolver/dns_key.c
@@ -0,0 +1,211 @@
1/* Key type used to cache DNS lookups made by the kernel
2 *
3 * See Documentation/networking/dns_resolver.txt
4 *
5 * Copyright (c) 2007 Igor Mammedov
6 * Author(s): Igor Mammedov (niallain@gmail.com)
7 * Steve French (sfrench@us.ibm.com)
8 * Wang Lei (wang840925@gmail.com)
9 * David Howells (dhowells@redhat.com)
10 *
11 * This library is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published
13 * by the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/kernel.h>
30#include <linux/keyctl.h>
31#include <linux/err.h>
32#include <keys/dns_resolver-type.h>
33#include <keys/user-type.h>
34#include "internal.h"
35
36MODULE_DESCRIPTION("DNS Resolver");
37MODULE_AUTHOR("Wang Lei");
38MODULE_LICENSE("GPL");
39
40unsigned dns_resolver_debug;
41module_param_named(debug, dns_resolver_debug, uint, S_IWUSR | S_IRUGO);
42MODULE_PARM_DESC(debug, "DNS Resolver debugging mask");
43
44const struct cred *dns_resolver_cache;
45
46/*
47 * Instantiate a user defined key for dns_resolver.
48 *
49 * The data must be a NUL-terminated string, with the NUL char accounted in
50 * datalen.
51 *
52 * If the data contains a '#' characters, then we take the clause after each
53 * one to be an option of the form 'key=value'. The actual data of interest is
54 * the string leading up to the first '#'. For instance:
55 *
56 * "ip1,ip2,...#foo=bar"
57 */
58static int
59dns_resolver_instantiate(struct key *key, const void *_data, size_t datalen)
60{
61 struct user_key_payload *upayload;
62 int ret;
63 size_t result_len = 0;
64 const char *data = _data, *opt;
65
66 kenter("%%%d,%s,'%s',%zu",
67 key->serial, key->description, data, datalen);
68
69 if (datalen <= 1 || !data || data[datalen - 1] != '\0')
70 return -EINVAL;
71 datalen--;
72
73 /* deal with any options embedded in the data */
74 opt = memchr(data, '#', datalen);
75 if (!opt) {
76 kdebug("no options currently supported");
77 return -EINVAL;
78 }
79
80 result_len = datalen;
81 ret = key_payload_reserve(key, result_len);
82 if (ret < 0)
83 return -EINVAL;
84
85 upayload = kmalloc(sizeof(*upayload) + result_len + 1, GFP_KERNEL);
86 if (!upayload) {
87 kleave(" = -ENOMEM");
88 return -ENOMEM;
89 }
90
91 upayload->datalen = result_len;
92 memcpy(upayload->data, data, result_len);
93 upayload->data[result_len] = '\0';
94 rcu_assign_pointer(key->payload.data, upayload);
95
96 kleave(" = 0");
97 return 0;
98}
99
100/*
101 * The description is of the form "[<type>:]<domain_name>"
102 *
103 * The domain name may be a simple name or an absolute domain name (which
104 * should end with a period). The domain name is case-independent.
105 */
106static int
107dns_resolver_match(const struct key *key, const void *description)
108{
109 int slen, dlen, ret = 0;
110 const char *src = key->description, *dsp = description;
111
112 kenter("%s,%s", src, dsp);
113
114 if (!src || !dsp)
115 goto no_match;
116
117 if (strcasecmp(src, dsp) == 0)
118 goto matched;
119
120 slen = strlen(src);
121 dlen = strlen(dsp);
122 if (slen <= 0 || dlen <= 0)
123 goto no_match;
124 if (src[slen - 1] == '.')
125 slen--;
126 if (dsp[dlen - 1] == '.')
127 dlen--;
128 if (slen != dlen || strncasecmp(src, dsp, slen) != 0)
129 goto no_match;
130
131matched:
132 ret = 1;
133no_match:
134 kleave(" = %d", ret);
135 return ret;
136}
137
138struct key_type key_type_dns_resolver = {
139 .name = "dns_resolver",
140 .instantiate = dns_resolver_instantiate,
141 .match = dns_resolver_match,
142 .revoke = user_revoke,
143 .destroy = user_destroy,
144 .describe = user_describe,
145 .read = user_read,
146};
147
148static int __init init_dns_resolver(void)
149{
150 struct cred *cred;
151 struct key *keyring;
152 int ret;
153
154 printk(KERN_NOTICE "Registering the %s key type\n",
155 key_type_dns_resolver.name);
156
157 /* create an override credential set with a special thread keyring in
158 * which DNS requests are cached
159 *
160 * this is used to prevent malicious redirections from being installed
161 * with add_key().
162 */
163 cred = prepare_kernel_cred(NULL);
164 if (!cred)
165 return -ENOMEM;
166
167 keyring = key_alloc(&key_type_keyring, ".dns_resolver", 0, 0, cred,
168 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
169 KEY_USR_VIEW | KEY_USR_READ,
170 KEY_ALLOC_NOT_IN_QUOTA);
171 if (IS_ERR(keyring)) {
172 ret = PTR_ERR(keyring);
173 goto failed_put_cred;
174 }
175
176 ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
177 if (ret < 0)
178 goto failed_put_key;
179
180 ret = register_key_type(&key_type_dns_resolver);
181 if (ret < 0)
182 goto failed_put_key;
183
184 /* instruct request_key() to use this special keyring as a cache for
185 * the results it looks up */
186 cred->thread_keyring = keyring;
187 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
188 dns_resolver_cache = cred;
189
190 kdebug("DNS resolver keyring: %d\n", key_serial(keyring));
191 return 0;
192
193failed_put_key:
194 key_put(keyring);
195failed_put_cred:
196 put_cred(cred);
197 return ret;
198}
199
200static void __exit exit_dns_resolver(void)
201{
202 key_revoke(dns_resolver_cache->thread_keyring);
203 unregister_key_type(&key_type_dns_resolver);
204 put_cred(dns_resolver_cache);
205 printk(KERN_NOTICE "Unregistered %s key type\n",
206 key_type_dns_resolver.name);
207}
208
209module_init(init_dns_resolver)
210module_exit(exit_dns_resolver)
211MODULE_LICENSE("GPL");
diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
new file mode 100644
index 000000000000..03d5255f5cf2
--- /dev/null
+++ b/net/dns_resolver/dns_query.c
@@ -0,0 +1,160 @@
1/* Upcall routine, designed to work as a key type and working through
2 * /sbin/request-key to contact userspace when handling DNS queries.
3 *
4 * See Documentation/networking/dns_resolver.txt
5 *
6 * Copyright (c) 2007 Igor Mammedov
7 * Author(s): Igor Mammedov (niallain@gmail.com)
8 * Steve French (sfrench@us.ibm.com)
9 * Wang Lei (wang840925@gmail.com)
10 * David Howells (dhowells@redhat.com)
11 *
12 * The upcall wrapper used to make an arbitrary DNS query.
13 *
14 * This function requires the appropriate userspace tool dns.upcall to be
15 * installed and something like the following lines should be added to the
16 * /etc/request-key.conf file:
17 *
18 * create dns_resolver * * /sbin/dns.upcall %k
19 *
20 * For example to use this module to query AFSDB RR:
21 *
22 * create dns_resolver afsdb:* * /sbin/dns.afsdb %k
23 *
24 * This library is free software; you can redistribute it and/or modify
25 * it under the terms of the GNU Lesser General Public License as published
26 * by the Free Software Foundation; either version 2.1 of the License, or
27 * (at your option) any later version.
28 *
29 * This library is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
32 * the GNU Lesser General Public License for more details.
33 *
34 * You should have received a copy of the GNU Lesser General Public License
35 * along with this library; if not, write to the Free Software
36 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 */
38
39#include <linux/module.h>
40#include <linux/slab.h>
41#include <linux/dns_resolver.h>
42#include <linux/err.h>
43#include <keys/dns_resolver-type.h>
44#include <keys/user-type.h>
45
46#include "internal.h"
47
48/**
49 * dns_query - Query the DNS
50 * @type: Query type (or NULL for straight host->IP lookup)
51 * @name: Name to look up
52 * @namelen: Length of name
53 * @options: Request options (or NULL if no options)
54 * @_result: Where to place the returned data.
55 * @_expiry: Where to store the result expiry time (or NULL)
56 *
57 * The data will be returned in the pointer at *result, and the caller is
58 * responsible for freeing it.
59 *
60 * The description should be of the form "[<query_type>:]<domain_name>", and
61 * the options need to be appropriate for the query type requested. If no
62 * query_type is given, then the query is a straight hostname to IP address
63 * lookup.
64 *
65 * The DNS resolution lookup is performed by upcalling to userspace by way of
66 * requesting a key of type dns_resolver.
67 *
68 * Returns the size of the result on success, -ve error code otherwise.
69 */
70int dns_query(const char *type, const char *name, size_t namelen,
71 const char *options, char **_result, time_t *_expiry)
72{
73 struct key *rkey;
74 struct user_key_payload *upayload;
75 const struct cred *saved_cred;
76 size_t typelen, desclen;
77 char *desc, *cp;
78 int ret, len;
79
80 kenter("%s,%*.*s,%zu,%s",
81 type, (int)namelen, (int)namelen, name, namelen, options);
82
83 if (!name || namelen == 0 || !_result)
84 return -EINVAL;
85
86 /* construct the query key description as "[<type>:]<name>" */
87 typelen = 0;
88 desclen = 0;
89 if (type) {
90 typelen = strlen(type);
91 if (typelen < 1)
92 return -EINVAL;
93 desclen += typelen + 1;
94 }
95
96 if (!namelen)
97 namelen = strlen(name);
98 if (namelen < 3)
99 return -EINVAL;
100 desclen += namelen + 1;
101
102 desc = kmalloc(desclen, GFP_KERNEL);
103 if (!desc)
104 return -ENOMEM;
105
106 cp = desc;
107 if (type) {
108 memcpy(cp, type, typelen);
109 cp += typelen;
110 *cp++ = ':';
111 }
112 memcpy(cp, name, namelen);
113 cp += namelen;
114 *cp = '\0';
115
116 if (!options)
117 options = "";
118 kdebug("call request_key(,%s,%s)", desc, options);
119
120 /* make the upcall, using special credentials to prevent the use of
121 * add_key() to preinstall malicious redirections
122 */
123 saved_cred = override_creds(dns_resolver_cache);
124 rkey = request_key(&key_type_dns_resolver, desc, options);
125 revert_creds(saved_cred);
126 kfree(desc);
127 if (IS_ERR(rkey)) {
128 ret = PTR_ERR(rkey);
129 goto out;
130 }
131
132 down_read(&rkey->sem);
133 rkey->perm |= KEY_USR_VIEW;
134
135 ret = key_validate(rkey);
136 if (ret < 0)
137 goto put;
138
139 upayload = rcu_dereference_protected(rkey->payload.data,
140 lockdep_is_held(&rkey->sem));
141 len = upayload->datalen;
142
143 ret = -ENOMEM;
144 *_result = kmalloc(len + 1, GFP_KERNEL);
145 if (!*_result)
146 goto put;
147
148 memcpy(*_result, upayload->data, len + 1);
149 if (_expiry)
150 *_expiry = rkey->expiry;
151
152 ret = len;
153put:
154 up_read(&rkey->sem);
155 key_put(rkey);
156out:
157 kleave(" = %d", ret);
158 return ret;
159}
160EXPORT_SYMBOL(dns_query);
diff --git a/net/dns_resolver/internal.h b/net/dns_resolver/internal.h
new file mode 100644
index 000000000000..189ca9e9b785
--- /dev/null
+++ b/net/dns_resolver/internal.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2010 Wang Lei
3 * Author(s): Wang Lei (wang840925@gmail.com). All Rights Reserved.
4 *
5 * Internal DNS Rsolver stuff
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/compiler.h>
23#include <linux/kernel.h>
24#include <linux/sched.h>
25
26/*
27 * dns_key.c
28 */
29extern const struct cred *dns_resolver_cache;
30
31/*
32 * debug tracing
33 */
34extern unsigned dns_resolver_debug;
35
36#define kdebug(FMT, ...) \
37do { \
38 if (unlikely(dns_resolver_debug)) \
39 printk(KERN_DEBUG "[%-6.6s] "FMT"\n", \
40 current->comm, ##__VA_ARGS__); \
41} while (0)
42
43#define kenter(FMT, ...) kdebug("==> %s("FMT")", __func__, ##__VA_ARGS__)
44#define kleave(FMT, ...) kdebug("<== %s()"FMT"", __func__, ##__VA_ARGS__)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3c426cb318e7..e663b78a2ef6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3930,7 +3930,7 @@ u8 *tcp_parse_md5sig_option(struct tcphdr *th)
3930 if (opsize < 2 || opsize > length) 3930 if (opsize < 2 || opsize > length)
3931 return NULL; 3931 return NULL;
3932 if (opcode == TCPOPT_MD5SIG) 3932 if (opcode == TCPOPT_MD5SIG)
3933 return ptr; 3933 return opsize == TCPOLEN_MD5SIG ? ptr : NULL;
3934 } 3934 }
3935 ptr += opsize - 2; 3935 ptr += opsize - 2;
3936 length -= opsize; 3936 length -= opsize;
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 800bc53b7f63..dfe7b38dd4af 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -20,7 +20,7 @@
20/* Please put other headers in irnet.h - Thanks */ 20/* Please put other headers in irnet.h - Thanks */
21 21
22/* Generic PPP callbacks (to call us) */ 22/* Generic PPP callbacks (to call us) */
23static struct ppp_channel_ops irnet_ppp_ops = { 23static const struct ppp_channel_ops irnet_ppp_ops = {
24 .start_xmit = ppp_irnet_send, 24 .start_xmit = ppp_irnet_send,
25 .ioctl = ppp_irnet_ioctl 25 .ioctl = ppp_irnet_ioctl
26}; 26};
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 90d82b3f2889..ff954b3e94b6 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -135,7 +135,10 @@ struct pppol2tp_session {
135 135
136static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); 136static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb);
137 137
138static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL }; 138static const struct ppp_channel_ops pppol2tp_chan_ops = {
139 .start_xmit = pppol2tp_xmit,
140};
141
139static const struct proto_ops pppol2tp_ops; 142static const struct proto_ops pppol2tp_ops;
140 143
141/* Helpers to obtain tunnel/session contexts from sockets. 144/* Helpers to obtain tunnel/session contexts from sockets.
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 7cc4f913a431..798a91b100cc 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -685,10 +685,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
685 685
686 return 0; 686 return 0;
687 687
688#ifdef CONFIG_INET
688 fail_ifa: 689 fail_ifa:
689 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY, 690 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
690 &local->network_latency_notifier); 691 &local->network_latency_notifier);
691 rtnl_lock(); 692 rtnl_lock();
693#endif
692 fail_pm_qos: 694 fail_pm_qos:
693 ieee80211_led_exit(local); 695 ieee80211_led_exit(local);
694 ieee80211_remove_interfaces(local); 696 ieee80211_remove_interfaces(local);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 41f20fb7e670..872d7b6ef6b3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -400,19 +400,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
400 else 400 else
401 __set_bit(SCAN_SW_SCANNING, &local->scanning); 401 __set_bit(SCAN_SW_SCANNING, &local->scanning);
402 402
403 /*
404 * Kicking off the scan need not be protected,
405 * only the scan variable stuff, since now
406 * local->scan_req is assigned and other callers
407 * will abort their scan attempts.
408 *
409 * This avoids too many locking dependencies
410 * so that the scan completed calls have more
411 * locking freedom.
412 */
413
414 ieee80211_recalc_idle(local); 403 ieee80211_recalc_idle(local);
415 mutex_unlock(&local->scan_mtx);
416 404
417 if (local->ops->hw_scan) { 405 if (local->ops->hw_scan) {
418 WARN_ON(!ieee80211_prep_hw_scan(local)); 406 WARN_ON(!ieee80211_prep_hw_scan(local));
@@ -420,8 +408,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
420 } else 408 } else
421 rc = ieee80211_start_sw_scan(local); 409 rc = ieee80211_start_sw_scan(local);
422 410
423 mutex_lock(&local->scan_mtx);
424
425 if (rc) { 411 if (rc) {
426 kfree(local->hw_scan_req); 412 kfree(local->hw_scan_req);
427 local->hw_scan_req = NULL; 413 local->hw_scan_req = NULL;
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c
index 2714da167fb8..b6ffe4e1b84a 100644
--- a/net/rxrpc/ar-ack.c
+++ b/net/rxrpc/ar-ack.c
@@ -245,6 +245,9 @@ static void rxrpc_resend_timer(struct rxrpc_call *call)
245 _enter("%d,%d,%d", 245 _enter("%d,%d,%d",
246 call->acks_tail, call->acks_unacked, call->acks_head); 246 call->acks_tail, call->acks_unacked, call->acks_head);
247 247
248 if (call->state >= RXRPC_CALL_COMPLETE)
249 return;
250
248 resend = 0; 251 resend = 0;
249 resend_at = 0; 252 resend_at = 0;
250 253
diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c
index 909d092de9f4..bf656c230ba9 100644
--- a/net/rxrpc/ar-call.c
+++ b/net/rxrpc/ar-call.c
@@ -786,6 +786,7 @@ static void rxrpc_call_life_expired(unsigned long _call)
786 786
787/* 787/*
788 * handle resend timer expiry 788 * handle resend timer expiry
789 * - may not take call->state_lock as this can deadlock against del_timer_sync()
789 */ 790 */
790static void rxrpc_resend_time_expired(unsigned long _call) 791static void rxrpc_resend_time_expired(unsigned long _call)
791{ 792{
@@ -796,12 +797,9 @@ static void rxrpc_resend_time_expired(unsigned long _call)
796 if (call->state >= RXRPC_CALL_COMPLETE) 797 if (call->state >= RXRPC_CALL_COMPLETE)
797 return; 798 return;
798 799
799 read_lock_bh(&call->state_lock);
800 clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); 800 clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
801 if (call->state < RXRPC_CALL_COMPLETE && 801 if (!test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events))
802 !test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events))
803 rxrpc_queue_call(call); 802 rxrpc_queue_call(call);
804 read_unlock_bh(&call->state_lock);
805} 803}
806 804
807/* 805/*
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index d0386a413e8d..509a2d53a99d 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -114,6 +114,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
114 int egress; 114 int egress;
115 int action; 115 int action;
116 int ihl; 116 int ihl;
117 int noff;
117 118
118 spin_lock(&p->tcf_lock); 119 spin_lock(&p->tcf_lock);
119 120
@@ -132,7 +133,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
132 if (unlikely(action == TC_ACT_SHOT)) 133 if (unlikely(action == TC_ACT_SHOT))
133 goto drop; 134 goto drop;
134 135
135 if (!pskb_may_pull(skb, sizeof(*iph))) 136 noff = skb_network_offset(skb);
137 if (!pskb_may_pull(skb, sizeof(*iph) + noff))
136 goto drop; 138 goto drop;
137 139
138 iph = ip_hdr(skb); 140 iph = ip_hdr(skb);
@@ -144,7 +146,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
144 146
145 if (!((old_addr ^ addr) & mask)) { 147 if (!((old_addr ^ addr) & mask)) {
146 if (skb_cloned(skb) && 148 if (skb_cloned(skb) &&
147 !skb_clone_writable(skb, sizeof(*iph)) && 149 !skb_clone_writable(skb, sizeof(*iph) + noff) &&
148 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 150 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
149 goto drop; 151 goto drop;
150 152
@@ -172,9 +174,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
172 { 174 {
173 struct tcphdr *tcph; 175 struct tcphdr *tcph;
174 176
175 if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) || 177 if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) ||
176 (skb_cloned(skb) && 178 (skb_cloned(skb) &&
177 !skb_clone_writable(skb, ihl + sizeof(*tcph)) && 179 !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) &&
178 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 180 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
179 goto drop; 181 goto drop;
180 182
@@ -186,9 +188,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
186 { 188 {
187 struct udphdr *udph; 189 struct udphdr *udph;
188 190
189 if (!pskb_may_pull(skb, ihl + sizeof(*udph)) || 191 if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) ||
190 (skb_cloned(skb) && 192 (skb_cloned(skb) &&
191 !skb_clone_writable(skb, ihl + sizeof(*udph)) && 193 !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) &&
192 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 194 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
193 goto drop; 195 goto drop;
194 196
@@ -205,7 +207,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
205 { 207 {
206 struct icmphdr *icmph; 208 struct icmphdr *icmph;
207 209
208 if (!pskb_may_pull(skb, ihl + sizeof(*icmph))) 210 if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + noff))
209 goto drop; 211 goto drop;
210 212
211 icmph = (void *)(skb_network_header(skb) + ihl); 213 icmph = (void *)(skb_network_header(skb) + ihl);
@@ -215,7 +217,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
215 (icmph->type != ICMP_PARAMETERPROB)) 217 (icmph->type != ICMP_PARAMETERPROB))
216 break; 218 break;
217 219
218 if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) 220 if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph) +
221 noff))
219 goto drop; 222 goto drop;
220 223
221 icmph = (void *)(skb_network_header(skb) + ihl); 224 icmph = (void *)(skb_network_header(skb) + ihl);
@@ -229,8 +232,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
229 break; 232 break;
230 233
231 if (skb_cloned(skb) && 234 if (skb_cloned(skb) &&
232 !skb_clone_writable(skb, 235 !skb_clone_writable(skb, ihl + sizeof(*icmph) +
233 ihl + sizeof(*icmph) + sizeof(*iph)) && 236 sizeof(*iph) + noff) &&
234 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 237 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
235 goto drop; 238 goto drop;
236 239
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index f73542d2cdd0..e17096e3913c 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -65,37 +65,47 @@ static inline u32 addr_fold(void *addr)
65 return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0); 65 return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
66} 66}
67 67
68static u32 flow_get_src(const struct sk_buff *skb) 68static u32 flow_get_src(struct sk_buff *skb)
69{ 69{
70 switch (skb->protocol) { 70 switch (skb->protocol) {
71 case htons(ETH_P_IP): 71 case htons(ETH_P_IP):
72 return ntohl(ip_hdr(skb)->saddr); 72 if (pskb_network_may_pull(skb, sizeof(struct iphdr)))
73 return ntohl(ip_hdr(skb)->saddr);
74 break;
73 case htons(ETH_P_IPV6): 75 case htons(ETH_P_IPV6):
74 return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); 76 if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
75 default: 77 return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
76 return addr_fold(skb->sk); 78 break;
77 } 79 }
80
81 return addr_fold(skb->sk);
78} 82}
79 83
80static u32 flow_get_dst(const struct sk_buff *skb) 84static u32 flow_get_dst(struct sk_buff *skb)
81{ 85{
82 switch (skb->protocol) { 86 switch (skb->protocol) {
83 case htons(ETH_P_IP): 87 case htons(ETH_P_IP):
84 return ntohl(ip_hdr(skb)->daddr); 88 if (pskb_network_may_pull(skb, sizeof(struct iphdr)))
89 return ntohl(ip_hdr(skb)->daddr);
90 break;
85 case htons(ETH_P_IPV6): 91 case htons(ETH_P_IPV6):
86 return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); 92 if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
87 default: 93 return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
88 return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; 94 break;
89 } 95 }
96
97 return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
90} 98}
91 99
92static u32 flow_get_proto(const struct sk_buff *skb) 100static u32 flow_get_proto(struct sk_buff *skb)
93{ 101{
94 switch (skb->protocol) { 102 switch (skb->protocol) {
95 case htons(ETH_P_IP): 103 case htons(ETH_P_IP):
96 return ip_hdr(skb)->protocol; 104 return pskb_network_may_pull(skb, sizeof(struct iphdr)) ?
105 ip_hdr(skb)->protocol : 0;
97 case htons(ETH_P_IPV6): 106 case htons(ETH_P_IPV6):
98 return ipv6_hdr(skb)->nexthdr; 107 return pskb_network_may_pull(skb, sizeof(struct ipv6hdr)) ?
108 ipv6_hdr(skb)->nexthdr : 0;
99 default: 109 default:
100 return 0; 110 return 0;
101 } 111 }
@@ -116,58 +126,64 @@ static int has_ports(u8 protocol)
116 } 126 }
117} 127}
118 128
119static u32 flow_get_proto_src(const struct sk_buff *skb) 129static u32 flow_get_proto_src(struct sk_buff *skb)
120{ 130{
121 u32 res = 0;
122
123 switch (skb->protocol) { 131 switch (skb->protocol) {
124 case htons(ETH_P_IP): { 132 case htons(ETH_P_IP): {
125 struct iphdr *iph = ip_hdr(skb); 133 struct iphdr *iph;
126 134
135 if (!pskb_network_may_pull(skb, sizeof(*iph)))
136 break;
137 iph = ip_hdr(skb);
127 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 138 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
128 has_ports(iph->protocol)) 139 has_ports(iph->protocol) &&
129 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); 140 pskb_network_may_pull(skb, iph->ihl * 4 + 2))
141 return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
130 break; 142 break;
131 } 143 }
132 case htons(ETH_P_IPV6): { 144 case htons(ETH_P_IPV6): {
133 struct ipv6hdr *iph = ipv6_hdr(skb); 145 struct ipv6hdr *iph;
134 146
147 if (!pskb_network_may_pull(skb, sizeof(*iph) + 2))
148 break;
149 iph = ipv6_hdr(skb);
135 if (has_ports(iph->nexthdr)) 150 if (has_ports(iph->nexthdr))
136 res = ntohs(*(__be16 *)&iph[1]); 151 return ntohs(*(__be16 *)&iph[1]);
137 break; 152 break;
138 } 153 }
139 default:
140 res = addr_fold(skb->sk);
141 } 154 }
142 155
143 return res; 156 return addr_fold(skb->sk);
144} 157}
145 158
146static u32 flow_get_proto_dst(const struct sk_buff *skb) 159static u32 flow_get_proto_dst(struct sk_buff *skb)
147{ 160{
148 u32 res = 0;
149
150 switch (skb->protocol) { 161 switch (skb->protocol) {
151 case htons(ETH_P_IP): { 162 case htons(ETH_P_IP): {
152 struct iphdr *iph = ip_hdr(skb); 163 struct iphdr *iph;
153 164
165 if (!pskb_network_may_pull(skb, sizeof(*iph)))
166 break;
167 iph = ip_hdr(skb);
154 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 168 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
155 has_ports(iph->protocol)) 169 has_ports(iph->protocol) &&
156 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); 170 pskb_network_may_pull(skb, iph->ihl * 4 + 4))
171 return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
157 break; 172 break;
158 } 173 }
159 case htons(ETH_P_IPV6): { 174 case htons(ETH_P_IPV6): {
160 struct ipv6hdr *iph = ipv6_hdr(skb); 175 struct ipv6hdr *iph;
161 176
177 if (!pskb_network_may_pull(skb, sizeof(*iph) + 4))
178 break;
179 iph = ipv6_hdr(skb);
162 if (has_ports(iph->nexthdr)) 180 if (has_ports(iph->nexthdr))
163 res = ntohs(*(__be16 *)((void *)&iph[1] + 2)); 181 return ntohs(*(__be16 *)((void *)&iph[1] + 2));
164 break; 182 break;
165 } 183 }
166 default:
167 res = addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
168 } 184 }
169 185
170 return res; 186 return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
171} 187}
172 188
173static u32 flow_get_iif(const struct sk_buff *skb) 189static u32 flow_get_iif(const struct sk_buff *skb)
@@ -211,7 +227,7 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
211}) 227})
212#endif 228#endif
213 229
214static u32 flow_get_nfct_src(const struct sk_buff *skb) 230static u32 flow_get_nfct_src(struct sk_buff *skb)
215{ 231{
216 switch (skb->protocol) { 232 switch (skb->protocol) {
217 case htons(ETH_P_IP): 233 case htons(ETH_P_IP):
@@ -223,7 +239,7 @@ fallback:
223 return flow_get_src(skb); 239 return flow_get_src(skb);
224} 240}
225 241
226static u32 flow_get_nfct_dst(const struct sk_buff *skb) 242static u32 flow_get_nfct_dst(struct sk_buff *skb)
227{ 243{
228 switch (skb->protocol) { 244 switch (skb->protocol) {
229 case htons(ETH_P_IP): 245 case htons(ETH_P_IP):
@@ -235,14 +251,14 @@ fallback:
235 return flow_get_dst(skb); 251 return flow_get_dst(skb);
236} 252}
237 253
238static u32 flow_get_nfct_proto_src(const struct sk_buff *skb) 254static u32 flow_get_nfct_proto_src(struct sk_buff *skb)
239{ 255{
240 return ntohs(CTTUPLE(skb, src.u.all)); 256 return ntohs(CTTUPLE(skb, src.u.all));
241fallback: 257fallback:
242 return flow_get_proto_src(skb); 258 return flow_get_proto_src(skb);
243} 259}
244 260
245static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb) 261static u32 flow_get_nfct_proto_dst(struct sk_buff *skb)
246{ 262{
247 return ntohs(CTTUPLE(skb, dst.u.all)); 263 return ntohs(CTTUPLE(skb, dst.u.all));
248fallback: 264fallback:
@@ -281,7 +297,7 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb)
281 return tag & VLAN_VID_MASK; 297 return tag & VLAN_VID_MASK;
282} 298}
283 299
284static u32 flow_key_get(const struct sk_buff *skb, int key) 300static u32 flow_key_get(struct sk_buff *skb, int key)
285{ 301{
286 switch (key) { 302 switch (key) {
287 case FLOW_KEY_SRC: 303 case FLOW_KEY_SRC:
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index dd9414e44200..425a1790b048 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -143,9 +143,17 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
143 u8 tunnelid = 0; 143 u8 tunnelid = 0;
144 u8 *xprt; 144 u8 *xprt;
145#if RSVP_DST_LEN == 4 145#if RSVP_DST_LEN == 4
146 struct ipv6hdr *nhptr = ipv6_hdr(skb); 146 struct ipv6hdr *nhptr;
147
148 if (!pskb_network_may_pull(skb, sizeof(*nhptr)))
149 return -1;
150 nhptr = ipv6_hdr(skb);
147#else 151#else
148 struct iphdr *nhptr = ip_hdr(skb); 152 struct iphdr *nhptr;
153
154 if (!pskb_network_may_pull(skb, sizeof(*nhptr)))
155 return -1;
156 nhptr = ip_hdr(skb);
149#endif 157#endif
150 158
151restart: 159restart:
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index c65762823f5e..534f33231c17 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -122,7 +122,11 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
122 switch (skb->protocol) { 122 switch (skb->protocol) {
123 case htons(ETH_P_IP): 123 case htons(ETH_P_IP):
124 { 124 {
125 const struct iphdr *iph = ip_hdr(skb); 125 const struct iphdr *iph;
126
127 if (!pskb_network_may_pull(skb, sizeof(*iph)))
128 goto err;
129 iph = ip_hdr(skb);
126 h = (__force u32)iph->daddr; 130 h = (__force u32)iph->daddr;
127 h2 = (__force u32)iph->saddr ^ iph->protocol; 131 h2 = (__force u32)iph->saddr ^ iph->protocol;
128 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 132 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
@@ -131,25 +135,32 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
131 iph->protocol == IPPROTO_UDPLITE || 135 iph->protocol == IPPROTO_UDPLITE ||
132 iph->protocol == IPPROTO_SCTP || 136 iph->protocol == IPPROTO_SCTP ||
133 iph->protocol == IPPROTO_DCCP || 137 iph->protocol == IPPROTO_DCCP ||
134 iph->protocol == IPPROTO_ESP)) 138 iph->protocol == IPPROTO_ESP) &&
139 pskb_network_may_pull(skb, iph->ihl * 4 + 4))
135 h2 ^= *(((u32*)iph) + iph->ihl); 140 h2 ^= *(((u32*)iph) + iph->ihl);
136 break; 141 break;
137 } 142 }
138 case htons(ETH_P_IPV6): 143 case htons(ETH_P_IPV6):
139 { 144 {
140 struct ipv6hdr *iph = ipv6_hdr(skb); 145 struct ipv6hdr *iph;
146
147 if (!pskb_network_may_pull(skb, sizeof(*iph)))
148 goto err;
149 iph = ipv6_hdr(skb);
141 h = (__force u32)iph->daddr.s6_addr32[3]; 150 h = (__force u32)iph->daddr.s6_addr32[3];
142 h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; 151 h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr;
143 if (iph->nexthdr == IPPROTO_TCP || 152 if ((iph->nexthdr == IPPROTO_TCP ||
144 iph->nexthdr == IPPROTO_UDP || 153 iph->nexthdr == IPPROTO_UDP ||
145 iph->nexthdr == IPPROTO_UDPLITE || 154 iph->nexthdr == IPPROTO_UDPLITE ||
146 iph->nexthdr == IPPROTO_SCTP || 155 iph->nexthdr == IPPROTO_SCTP ||
147 iph->nexthdr == IPPROTO_DCCP || 156 iph->nexthdr == IPPROTO_DCCP ||
148 iph->nexthdr == IPPROTO_ESP) 157 iph->nexthdr == IPPROTO_ESP) &&
158 pskb_network_may_pull(skb, sizeof(*iph) + 4))
149 h2 ^= *(u32*)&iph[1]; 159 h2 ^= *(u32*)&iph[1];
150 break; 160 break;
151 } 161 }
152 default: 162 default:
163err:
153 h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; 164 h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol;
154 h2 = (unsigned long)skb->sk; 165 h2 = (unsigned long)skb->sk;
155 } 166 }
@@ -502,6 +513,12 @@ static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
502 return 0; 513 return 0;
503} 514}
504 515
516static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
517 u32 classid)
518{
519 return 0;
520}
521
505static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) 522static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
506{ 523{
507 struct sfq_sched_data *q = qdisc_priv(sch); 524 struct sfq_sched_data *q = qdisc_priv(sch);
@@ -556,6 +573,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
556static const struct Qdisc_class_ops sfq_class_ops = { 573static const struct Qdisc_class_ops sfq_class_ops = {
557 .get = sfq_get, 574 .get = sfq_get,
558 .tcf_chain = sfq_find_tcf, 575 .tcf_chain = sfq_find_tcf,
576 .bind_tcf = sfq_bind,
559 .dump = sfq_dump_class, 577 .dump = sfq_dump_class,
560 .dump_stats = sfq_dump_class_stats, 578 .dump_stats = sfq_dump_class_stats,
561 .walk = sfq_walk, 579 .walk = sfq_walk,
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 8dc47f1d0001..880d0de3f50f 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -19,6 +19,15 @@
19# define RPCDBG_FACILITY RPCDBG_AUTH 19# define RPCDBG_FACILITY RPCDBG_AUTH
20#endif 20#endif
21 21
22#define RPC_CREDCACHE_DEFAULT_HASHBITS (4)
23struct rpc_cred_cache {
24 struct hlist_head *hashtable;
25 unsigned int hashbits;
26 spinlock_t lock;
27};
28
29static unsigned int auth_hashbits = RPC_CREDCACHE_DEFAULT_HASHBITS;
30
22static DEFINE_SPINLOCK(rpc_authflavor_lock); 31static DEFINE_SPINLOCK(rpc_authflavor_lock);
23static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { 32static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
24 &authnull_ops, /* AUTH_NULL */ 33 &authnull_ops, /* AUTH_NULL */
@@ -29,6 +38,42 @@ static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
29static LIST_HEAD(cred_unused); 38static LIST_HEAD(cred_unused);
30static unsigned long number_cred_unused; 39static unsigned long number_cred_unused;
31 40
41#define MAX_HASHTABLE_BITS (10)
42static int param_set_hashtbl_sz(const char *val, struct kernel_param *kp)
43{
44 unsigned long num;
45 unsigned int nbits;
46 int ret;
47
48 if (!val)
49 goto out_inval;
50 ret = strict_strtoul(val, 0, &num);
51 if (ret == -EINVAL)
52 goto out_inval;
53 nbits = fls(num);
54 if (num > (1U << nbits))
55 nbits++;
56 if (nbits > MAX_HASHTABLE_BITS || nbits < 2)
57 goto out_inval;
58 *(unsigned int *)kp->arg = nbits;
59 return 0;
60out_inval:
61 return -EINVAL;
62}
63
64static int param_get_hashtbl_sz(char *buffer, struct kernel_param *kp)
65{
66 unsigned int nbits;
67
68 nbits = *(unsigned int *)kp->arg;
69 return sprintf(buffer, "%u", 1U << nbits);
70}
71
72#define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int);
73
74module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644);
75MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
76
32static u32 77static u32
33pseudoflavor_to_flavor(u32 flavor) { 78pseudoflavor_to_flavor(u32 flavor) {
34 if (flavor >= RPC_AUTH_MAXFLAVOR) 79 if (flavor >= RPC_AUTH_MAXFLAVOR)
@@ -145,16 +190,23 @@ int
145rpcauth_init_credcache(struct rpc_auth *auth) 190rpcauth_init_credcache(struct rpc_auth *auth)
146{ 191{
147 struct rpc_cred_cache *new; 192 struct rpc_cred_cache *new;
148 int i; 193 unsigned int hashsize;
149 194
150 new = kmalloc(sizeof(*new), GFP_KERNEL); 195 new = kmalloc(sizeof(*new), GFP_KERNEL);
151 if (!new) 196 if (!new)
152 return -ENOMEM; 197 goto out_nocache;
153 for (i = 0; i < RPC_CREDCACHE_NR; i++) 198 new->hashbits = auth_hashbits;
154 INIT_HLIST_HEAD(&new->hashtable[i]); 199 hashsize = 1U << new->hashbits;
200 new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL);
201 if (!new->hashtable)
202 goto out_nohashtbl;
155 spin_lock_init(&new->lock); 203 spin_lock_init(&new->lock);
156 auth->au_credcache = new; 204 auth->au_credcache = new;
157 return 0; 205 return 0;
206out_nohashtbl:
207 kfree(new);
208out_nocache:
209 return -ENOMEM;
158} 210}
159EXPORT_SYMBOL_GPL(rpcauth_init_credcache); 211EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
160 212
@@ -183,11 +235,12 @@ rpcauth_clear_credcache(struct rpc_cred_cache *cache)
183 LIST_HEAD(free); 235 LIST_HEAD(free);
184 struct hlist_head *head; 236 struct hlist_head *head;
185 struct rpc_cred *cred; 237 struct rpc_cred *cred;
238 unsigned int hashsize = 1U << cache->hashbits;
186 int i; 239 int i;
187 240
188 spin_lock(&rpc_credcache_lock); 241 spin_lock(&rpc_credcache_lock);
189 spin_lock(&cache->lock); 242 spin_lock(&cache->lock);
190 for (i = 0; i < RPC_CREDCACHE_NR; i++) { 243 for (i = 0; i < hashsize; i++) {
191 head = &cache->hashtable[i]; 244 head = &cache->hashtable[i];
192 while (!hlist_empty(head)) { 245 while (!hlist_empty(head)) {
193 cred = hlist_entry(head->first, struct rpc_cred, cr_hash); 246 cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
@@ -216,6 +269,7 @@ rpcauth_destroy_credcache(struct rpc_auth *auth)
216 if (cache) { 269 if (cache) {
217 auth->au_credcache = NULL; 270 auth->au_credcache = NULL;
218 rpcauth_clear_credcache(cache); 271 rpcauth_clear_credcache(cache);
272 kfree(cache->hashtable);
219 kfree(cache); 273 kfree(cache);
220 } 274 }
221} 275}
@@ -297,7 +351,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
297 *entry, *new; 351 *entry, *new;
298 unsigned int nr; 352 unsigned int nr;
299 353
300 nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS); 354 nr = hash_long(acred->uid, cache->hashbits);
301 355
302 rcu_read_lock(); 356 rcu_read_lock();
303 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) { 357 hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
@@ -390,16 +444,16 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
390} 444}
391EXPORT_SYMBOL_GPL(rpcauth_init_cred); 445EXPORT_SYMBOL_GPL(rpcauth_init_cred);
392 446
393void 447struct rpc_cred *
394rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred, int lookupflags) 448rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred, int lookupflags)
395{ 449{
396 task->tk_msg.rpc_cred = get_rpccred(cred);
397 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid, 450 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
398 cred->cr_auth->au_ops->au_name, cred); 451 cred->cr_auth->au_ops->au_name, cred);
452 return get_rpccred(cred);
399} 453}
400EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred); 454EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred);
401 455
402static void 456static struct rpc_cred *
403rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags) 457rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
404{ 458{
405 struct rpc_auth *auth = task->tk_client->cl_auth; 459 struct rpc_auth *auth = task->tk_client->cl_auth;
@@ -407,45 +461,43 @@ rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
407 .uid = 0, 461 .uid = 0,
408 .gid = 0, 462 .gid = 0,
409 }; 463 };
410 struct rpc_cred *ret;
411 464
412 dprintk("RPC: %5u looking up %s cred\n", 465 dprintk("RPC: %5u looking up %s cred\n",
413 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); 466 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
414 ret = auth->au_ops->lookup_cred(auth, &acred, lookupflags); 467 return auth->au_ops->lookup_cred(auth, &acred, lookupflags);
415 if (!IS_ERR(ret))
416 task->tk_msg.rpc_cred = ret;
417 else
418 task->tk_status = PTR_ERR(ret);
419} 468}
420 469
421static void 470static struct rpc_cred *
422rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags) 471rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags)
423{ 472{
424 struct rpc_auth *auth = task->tk_client->cl_auth; 473 struct rpc_auth *auth = task->tk_client->cl_auth;
425 struct rpc_cred *ret;
426 474
427 dprintk("RPC: %5u looking up %s cred\n", 475 dprintk("RPC: %5u looking up %s cred\n",
428 task->tk_pid, auth->au_ops->au_name); 476 task->tk_pid, auth->au_ops->au_name);
429 ret = rpcauth_lookupcred(auth, lookupflags); 477 return rpcauth_lookupcred(auth, lookupflags);
430 if (!IS_ERR(ret))
431 task->tk_msg.rpc_cred = ret;
432 else
433 task->tk_status = PTR_ERR(ret);
434} 478}
435 479
436void 480static int
437rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags) 481rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
438{ 482{
483 struct rpc_rqst *req = task->tk_rqstp;
484 struct rpc_cred *new;
439 int lookupflags = 0; 485 int lookupflags = 0;
440 486
441 if (flags & RPC_TASK_ASYNC) 487 if (flags & RPC_TASK_ASYNC)
442 lookupflags |= RPCAUTH_LOOKUP_NEW; 488 lookupflags |= RPCAUTH_LOOKUP_NEW;
443 if (cred != NULL) 489 if (cred != NULL)
444 cred->cr_ops->crbind(task, cred, lookupflags); 490 new = cred->cr_ops->crbind(task, cred, lookupflags);
445 else if (flags & RPC_TASK_ROOTCREDS) 491 else if (flags & RPC_TASK_ROOTCREDS)
446 rpcauth_bind_root_cred(task, lookupflags); 492 new = rpcauth_bind_root_cred(task, lookupflags);
447 else 493 else
448 rpcauth_bind_new_cred(task, lookupflags); 494 new = rpcauth_bind_new_cred(task, lookupflags);
495 if (IS_ERR(new))
496 return PTR_ERR(new);
497 if (req->rq_cred != NULL)
498 put_rpccred(req->rq_cred);
499 req->rq_cred = new;
500 return 0;
449} 501}
450 502
451void 503void
@@ -484,22 +536,10 @@ out_nodestroy:
484} 536}
485EXPORT_SYMBOL_GPL(put_rpccred); 537EXPORT_SYMBOL_GPL(put_rpccred);
486 538
487void
488rpcauth_unbindcred(struct rpc_task *task)
489{
490 struct rpc_cred *cred = task->tk_msg.rpc_cred;
491
492 dprintk("RPC: %5u releasing %s cred %p\n",
493 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
494
495 put_rpccred(cred);
496 task->tk_msg.rpc_cred = NULL;
497}
498
499__be32 * 539__be32 *
500rpcauth_marshcred(struct rpc_task *task, __be32 *p) 540rpcauth_marshcred(struct rpc_task *task, __be32 *p)
501{ 541{
502 struct rpc_cred *cred = task->tk_msg.rpc_cred; 542 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
503 543
504 dprintk("RPC: %5u marshaling %s cred %p\n", 544 dprintk("RPC: %5u marshaling %s cred %p\n",
505 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 545 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
@@ -510,7 +550,7 @@ rpcauth_marshcred(struct rpc_task *task, __be32 *p)
510__be32 * 550__be32 *
511rpcauth_checkverf(struct rpc_task *task, __be32 *p) 551rpcauth_checkverf(struct rpc_task *task, __be32 *p)
512{ 552{
513 struct rpc_cred *cred = task->tk_msg.rpc_cred; 553 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
514 554
515 dprintk("RPC: %5u validating %s cred %p\n", 555 dprintk("RPC: %5u validating %s cred %p\n",
516 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 556 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
@@ -522,7 +562,7 @@ int
522rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, 562rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp,
523 __be32 *data, void *obj) 563 __be32 *data, void *obj)
524{ 564{
525 struct rpc_cred *cred = task->tk_msg.rpc_cred; 565 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
526 566
527 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", 567 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n",
528 task->tk_pid, cred->cr_ops->cr_name, cred); 568 task->tk_pid, cred->cr_ops->cr_name, cred);
@@ -536,7 +576,7 @@ int
536rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, 576rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
537 __be32 *data, void *obj) 577 __be32 *data, void *obj)
538{ 578{
539 struct rpc_cred *cred = task->tk_msg.rpc_cred; 579 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
540 580
541 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", 581 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n",
542 task->tk_pid, cred->cr_ops->cr_name, cred); 582 task->tk_pid, cred->cr_ops->cr_name, cred);
@@ -550,13 +590,21 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp,
550int 590int
551rpcauth_refreshcred(struct rpc_task *task) 591rpcauth_refreshcred(struct rpc_task *task)
552{ 592{
553 struct rpc_cred *cred = task->tk_msg.rpc_cred; 593 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
554 int err; 594 int err;
555 595
596 cred = task->tk_rqstp->rq_cred;
597 if (cred == NULL) {
598 err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags);
599 if (err < 0)
600 goto out;
601 cred = task->tk_rqstp->rq_cred;
602 };
556 dprintk("RPC: %5u refreshing %s cred %p\n", 603 dprintk("RPC: %5u refreshing %s cred %p\n",
557 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 604 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
558 605
559 err = cred->cr_ops->crrefresh(task); 606 err = cred->cr_ops->crrefresh(task);
607out:
560 if (err < 0) 608 if (err < 0)
561 task->tk_status = err; 609 task->tk_status = err;
562 return err; 610 return err;
@@ -565,7 +613,7 @@ rpcauth_refreshcred(struct rpc_task *task)
565void 613void
566rpcauth_invalcred(struct rpc_task *task) 614rpcauth_invalcred(struct rpc_task *task)
567{ 615{
568 struct rpc_cred *cred = task->tk_msg.rpc_cred; 616 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
569 617
570 dprintk("RPC: %5u invalidating %s cred %p\n", 618 dprintk("RPC: %5u invalidating %s cred %p\n",
571 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 619 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
@@ -576,7 +624,7 @@ rpcauth_invalcred(struct rpc_task *task)
576int 624int
577rpcauth_uptodatecred(struct rpc_task *task) 625rpcauth_uptodatecred(struct rpc_task *task)
578{ 626{
579 struct rpc_cred *cred = task->tk_msg.rpc_cred; 627 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
580 628
581 return cred == NULL || 629 return cred == NULL ||
582 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; 630 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
@@ -587,14 +635,27 @@ static struct shrinker rpc_cred_shrinker = {
587 .seeks = DEFAULT_SEEKS, 635 .seeks = DEFAULT_SEEKS,
588}; 636};
589 637
590void __init rpcauth_init_module(void) 638int __init rpcauth_init_module(void)
591{ 639{
592 rpc_init_authunix(); 640 int err;
593 rpc_init_generic_auth(); 641
642 err = rpc_init_authunix();
643 if (err < 0)
644 goto out1;
645 err = rpc_init_generic_auth();
646 if (err < 0)
647 goto out2;
594 register_shrinker(&rpc_cred_shrinker); 648 register_shrinker(&rpc_cred_shrinker);
649 return 0;
650out2:
651 rpc_destroy_authunix();
652out1:
653 return err;
595} 654}
596 655
597void __exit rpcauth_remove_module(void) 656void __exit rpcauth_remove_module(void)
598{ 657{
658 rpc_destroy_authunix();
659 rpc_destroy_generic_auth();
599 unregister_shrinker(&rpc_cred_shrinker); 660 unregister_shrinker(&rpc_cred_shrinker);
600} 661}
diff --git a/net/sunrpc/auth_generic.c b/net/sunrpc/auth_generic.c
index 8f623b0f03dd..43162bb3b78f 100644
--- a/net/sunrpc/auth_generic.c
+++ b/net/sunrpc/auth_generic.c
@@ -27,7 +27,6 @@ struct generic_cred {
27}; 27};
28 28
29static struct rpc_auth generic_auth; 29static struct rpc_auth generic_auth;
30static struct rpc_cred_cache generic_cred_cache;
31static const struct rpc_credops generic_credops; 30static const struct rpc_credops generic_credops;
32 31
33/* 32/*
@@ -55,18 +54,13 @@ struct rpc_cred *rpc_lookup_machine_cred(void)
55} 54}
56EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred); 55EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
57 56
58static void 57static struct rpc_cred *generic_bind_cred(struct rpc_task *task,
59generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred, int lookupflags) 58 struct rpc_cred *cred, int lookupflags)
60{ 59{
61 struct rpc_auth *auth = task->tk_client->cl_auth; 60 struct rpc_auth *auth = task->tk_client->cl_auth;
62 struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred; 61 struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred;
63 struct rpc_cred *ret;
64 62
65 ret = auth->au_ops->lookup_cred(auth, acred, lookupflags); 63 return auth->au_ops->lookup_cred(auth, acred, lookupflags);
66 if (!IS_ERR(ret))
67 task->tk_msg.rpc_cred = ret;
68 else
69 task->tk_status = PTR_ERR(ret);
70} 64}
71 65
72/* 66/*
@@ -159,20 +153,16 @@ out_nomatch:
159 return 0; 153 return 0;
160} 154}
161 155
162void __init rpc_init_generic_auth(void) 156int __init rpc_init_generic_auth(void)
163{ 157{
164 spin_lock_init(&generic_cred_cache.lock); 158 return rpcauth_init_credcache(&generic_auth);
165} 159}
166 160
167void __exit rpc_destroy_generic_auth(void) 161void __exit rpc_destroy_generic_auth(void)
168{ 162{
169 rpcauth_clear_credcache(&generic_cred_cache); 163 rpcauth_destroy_credcache(&generic_auth);
170} 164}
171 165
172static struct rpc_cred_cache generic_cred_cache = {
173 {{ NULL, },},
174};
175
176static const struct rpc_authops generic_auth_ops = { 166static const struct rpc_authops generic_auth_ops = {
177 .owner = THIS_MODULE, 167 .owner = THIS_MODULE,
178 .au_name = "Generic", 168 .au_name = "Generic",
@@ -183,7 +173,6 @@ static const struct rpc_authops generic_auth_ops = {
183static struct rpc_auth generic_auth = { 173static struct rpc_auth generic_auth = {
184 .au_ops = &generic_auth_ops, 174 .au_ops = &generic_auth_ops,
185 .au_count = ATOMIC_INIT(0), 175 .au_count = ATOMIC_INIT(0),
186 .au_credcache = &generic_cred_cache,
187}; 176};
188 177
189static const struct rpc_credops generic_credops = { 178static const struct rpc_credops generic_credops = {
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 8da2a0e68574..dcfc66bab2bb 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -373,7 +373,7 @@ gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss
373static void 373static void
374gss_upcall_callback(struct rpc_task *task) 374gss_upcall_callback(struct rpc_task *task)
375{ 375{
376 struct gss_cred *gss_cred = container_of(task->tk_msg.rpc_cred, 376 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
377 struct gss_cred, gc_base); 377 struct gss_cred, gc_base);
378 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; 378 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
379 struct inode *inode = &gss_msg->inode->vfs_inode; 379 struct inode *inode = &gss_msg->inode->vfs_inode;
@@ -502,7 +502,7 @@ static void warn_gssd(void)
502static inline int 502static inline int
503gss_refresh_upcall(struct rpc_task *task) 503gss_refresh_upcall(struct rpc_task *task)
504{ 504{
505 struct rpc_cred *cred = task->tk_msg.rpc_cred; 505 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
506 struct gss_auth *gss_auth = container_of(cred->cr_auth, 506 struct gss_auth *gss_auth = container_of(cred->cr_auth,
507 struct gss_auth, rpc_auth); 507 struct gss_auth, rpc_auth);
508 struct gss_cred *gss_cred = container_of(cred, 508 struct gss_cred *gss_cred = container_of(cred,
@@ -928,6 +928,7 @@ gss_do_free_ctx(struct gss_cl_ctx *ctx)
928{ 928{
929 dprintk("RPC: gss_free_ctx\n"); 929 dprintk("RPC: gss_free_ctx\n");
930 930
931 gss_delete_sec_context(&ctx->gc_gss_ctx);
931 kfree(ctx->gc_wire_ctx.data); 932 kfree(ctx->gc_wire_ctx.data);
932 kfree(ctx); 933 kfree(ctx);
933} 934}
@@ -942,13 +943,7 @@ gss_free_ctx_callback(struct rcu_head *head)
942static void 943static void
943gss_free_ctx(struct gss_cl_ctx *ctx) 944gss_free_ctx(struct gss_cl_ctx *ctx)
944{ 945{
945 struct gss_ctx *gc_gss_ctx;
946
947 gc_gss_ctx = rcu_dereference(ctx->gc_gss_ctx);
948 rcu_assign_pointer(ctx->gc_gss_ctx, NULL);
949 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback); 946 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
950 if (gc_gss_ctx)
951 gss_delete_sec_context(&gc_gss_ctx);
952} 947}
953 948
954static void 949static void
@@ -1064,12 +1059,12 @@ out:
1064static __be32 * 1059static __be32 *
1065gss_marshal(struct rpc_task *task, __be32 *p) 1060gss_marshal(struct rpc_task *task, __be32 *p)
1066{ 1061{
1067 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1062 struct rpc_rqst *req = task->tk_rqstp;
1063 struct rpc_cred *cred = req->rq_cred;
1068 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1064 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1069 gc_base); 1065 gc_base);
1070 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1066 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1071 __be32 *cred_len; 1067 __be32 *cred_len;
1072 struct rpc_rqst *req = task->tk_rqstp;
1073 u32 maj_stat = 0; 1068 u32 maj_stat = 0;
1074 struct xdr_netobj mic; 1069 struct xdr_netobj mic;
1075 struct kvec iov; 1070 struct kvec iov;
@@ -1119,7 +1114,7 @@ out_put_ctx:
1119 1114
1120static int gss_renew_cred(struct rpc_task *task) 1115static int gss_renew_cred(struct rpc_task *task)
1121{ 1116{
1122 struct rpc_cred *oldcred = task->tk_msg.rpc_cred; 1117 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred;
1123 struct gss_cred *gss_cred = container_of(oldcred, 1118 struct gss_cred *gss_cred = container_of(oldcred,
1124 struct gss_cred, 1119 struct gss_cred,
1125 gc_base); 1120 gc_base);
@@ -1133,7 +1128,7 @@ static int gss_renew_cred(struct rpc_task *task)
1133 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW); 1128 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
1134 if (IS_ERR(new)) 1129 if (IS_ERR(new))
1135 return PTR_ERR(new); 1130 return PTR_ERR(new);
1136 task->tk_msg.rpc_cred = new; 1131 task->tk_rqstp->rq_cred = new;
1137 put_rpccred(oldcred); 1132 put_rpccred(oldcred);
1138 return 0; 1133 return 0;
1139} 1134}
@@ -1161,7 +1156,7 @@ static int gss_cred_is_negative_entry(struct rpc_cred *cred)
1161static int 1156static int
1162gss_refresh(struct rpc_task *task) 1157gss_refresh(struct rpc_task *task)
1163{ 1158{
1164 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1159 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1165 int ret = 0; 1160 int ret = 0;
1166 1161
1167 if (gss_cred_is_negative_entry(cred)) 1162 if (gss_cred_is_negative_entry(cred))
@@ -1172,7 +1167,7 @@ gss_refresh(struct rpc_task *task)
1172 ret = gss_renew_cred(task); 1167 ret = gss_renew_cred(task);
1173 if (ret < 0) 1168 if (ret < 0)
1174 goto out; 1169 goto out;
1175 cred = task->tk_msg.rpc_cred; 1170 cred = task->tk_rqstp->rq_cred;
1176 } 1171 }
1177 1172
1178 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) 1173 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
@@ -1191,7 +1186,7 @@ gss_refresh_null(struct rpc_task *task)
1191static __be32 * 1186static __be32 *
1192gss_validate(struct rpc_task *task, __be32 *p) 1187gss_validate(struct rpc_task *task, __be32 *p)
1193{ 1188{
1194 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1189 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1195 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1190 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1196 __be32 seq; 1191 __be32 seq;
1197 struct kvec iov; 1192 struct kvec iov;
@@ -1400,7 +1395,7 @@ static int
1400gss_wrap_req(struct rpc_task *task, 1395gss_wrap_req(struct rpc_task *task,
1401 kxdrproc_t encode, void *rqstp, __be32 *p, void *obj) 1396 kxdrproc_t encode, void *rqstp, __be32 *p, void *obj)
1402{ 1397{
1403 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1398 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1404 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1399 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1405 gc_base); 1400 gc_base);
1406 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1401 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
@@ -1503,7 +1498,7 @@ static int
1503gss_unwrap_resp(struct rpc_task *task, 1498gss_unwrap_resp(struct rpc_task *task,
1504 kxdrproc_t decode, void *rqstp, __be32 *p, void *obj) 1499 kxdrproc_t decode, void *rqstp, __be32 *p, void *obj)
1505{ 1500{
1506 struct rpc_cred *cred = task->tk_msg.rpc_cred; 1501 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1507 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1502 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1508 gc_base); 1503 gc_base);
1509 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1504 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index 1db618f56ecb..a5c36c01707b 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -75,7 +75,7 @@ nul_marshal(struct rpc_task *task, __be32 *p)
75static int 75static int
76nul_refresh(struct rpc_task *task) 76nul_refresh(struct rpc_task *task)
77{ 77{
78 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags); 78 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
79 return 0; 79 return 0;
80} 80}
81 81
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index aac2f8b4ee21..4cb70dc6e7ad 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -29,7 +29,6 @@ struct unx_cred {
29#endif 29#endif
30 30
31static struct rpc_auth unix_auth; 31static struct rpc_auth unix_auth;
32static struct rpc_cred_cache unix_cred_cache;
33static const struct rpc_credops unix_credops; 32static const struct rpc_credops unix_credops;
34 33
35static struct rpc_auth * 34static struct rpc_auth *
@@ -141,7 +140,7 @@ static __be32 *
141unx_marshal(struct rpc_task *task, __be32 *p) 140unx_marshal(struct rpc_task *task, __be32 *p)
142{ 141{
143 struct rpc_clnt *clnt = task->tk_client; 142 struct rpc_clnt *clnt = task->tk_client;
144 struct unx_cred *cred = container_of(task->tk_msg.rpc_cred, struct unx_cred, uc_base); 143 struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
145 __be32 *base, *hold; 144 __be32 *base, *hold;
146 int i; 145 int i;
147 146
@@ -174,7 +173,7 @@ unx_marshal(struct rpc_task *task, __be32 *p)
174static int 173static int
175unx_refresh(struct rpc_task *task) 174unx_refresh(struct rpc_task *task)
176{ 175{
177 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_msg.rpc_cred->cr_flags); 176 set_bit(RPCAUTH_CRED_UPTODATE, &task->tk_rqstp->rq_cred->cr_flags);
178 return 0; 177 return 0;
179} 178}
180 179
@@ -197,15 +196,20 @@ unx_validate(struct rpc_task *task, __be32 *p)
197 printk("RPC: giant verf size: %u\n", size); 196 printk("RPC: giant verf size: %u\n", size);
198 return NULL; 197 return NULL;
199 } 198 }
200 task->tk_msg.rpc_cred->cr_auth->au_rslack = (size >> 2) + 2; 199 task->tk_rqstp->rq_cred->cr_auth->au_rslack = (size >> 2) + 2;
201 p += (size >> 2); 200 p += (size >> 2);
202 201
203 return p; 202 return p;
204} 203}
205 204
206void __init rpc_init_authunix(void) 205int __init rpc_init_authunix(void)
207{ 206{
208 spin_lock_init(&unix_cred_cache.lock); 207 return rpcauth_init_credcache(&unix_auth);
208}
209
210void rpc_destroy_authunix(void)
211{
212 rpcauth_destroy_credcache(&unix_auth);
209} 213}
210 214
211const struct rpc_authops authunix_ops = { 215const struct rpc_authops authunix_ops = {
@@ -219,17 +223,12 @@ const struct rpc_authops authunix_ops = {
219}; 223};
220 224
221static 225static
222struct rpc_cred_cache unix_cred_cache = {
223};
224
225static
226struct rpc_auth unix_auth = { 226struct rpc_auth unix_auth = {
227 .au_cslack = UNX_WRITESLACK, 227 .au_cslack = UNX_WRITESLACK,
228 .au_rslack = 2, /* assume AUTH_NULL verf */ 228 .au_rslack = 2, /* assume AUTH_NULL verf */
229 .au_ops = &authunix_ops, 229 .au_ops = &authunix_ops,
230 .au_flavor = RPC_AUTH_UNIX, 230 .au_flavor = RPC_AUTH_UNIX,
231 .au_count = ATOMIC_INIT(0), 231 .au_count = ATOMIC_INIT(0),
232 .au_credcache = &unix_cred_cache,
233}; 232};
234 233
235static 234static
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 58de76c8540c..2b06410e584e 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -34,7 +34,6 @@
34#include <linux/sunrpc/cache.h> 34#include <linux/sunrpc/cache.h>
35#include <linux/sunrpc/stats.h> 35#include <linux/sunrpc/stats.h>
36#include <linux/sunrpc/rpc_pipe_fs.h> 36#include <linux/sunrpc/rpc_pipe_fs.h>
37#include <linux/smp_lock.h>
38 37
39#define RPCDBG_FACILITY RPCDBG_CACHE 38#define RPCDBG_FACILITY RPCDBG_CACHE
40 39
@@ -320,7 +319,7 @@ static struct cache_detail *current_detail;
320static int current_index; 319static int current_index;
321 320
322static void do_cache_clean(struct work_struct *work); 321static void do_cache_clean(struct work_struct *work);
323static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean); 322static struct delayed_work cache_cleaner;
324 323
325static void sunrpc_init_cache_detail(struct cache_detail *cd) 324static void sunrpc_init_cache_detail(struct cache_detail *cd)
326{ 325{
@@ -1504,6 +1503,11 @@ static int create_cache_proc_entries(struct cache_detail *cd)
1504} 1503}
1505#endif 1504#endif
1506 1505
1506void __init cache_initialize(void)
1507{
1508 INIT_DELAYED_WORK_DEFERRABLE(&cache_cleaner, do_cache_clean);
1509}
1510
1507int cache_register(struct cache_detail *cd) 1511int cache_register(struct cache_detail *cd)
1508{ 1512{
1509 int ret; 1513 int ret;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 756fc324db9e..2388d83b68ff 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -414,6 +414,35 @@ out_no_clnt:
414EXPORT_SYMBOL_GPL(rpc_clone_client); 414EXPORT_SYMBOL_GPL(rpc_clone_client);
415 415
416/* 416/*
417 * Kill all tasks for the given client.
418 * XXX: kill their descendants as well?
419 */
420void rpc_killall_tasks(struct rpc_clnt *clnt)
421{
422 struct rpc_task *rovr;
423
424
425 if (list_empty(&clnt->cl_tasks))
426 return;
427 dprintk("RPC: killing all tasks for client %p\n", clnt);
428 /*
429 * Spin lock all_tasks to prevent changes...
430 */
431 spin_lock(&clnt->cl_lock);
432 list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
433 if (!RPC_IS_ACTIVATED(rovr))
434 continue;
435 if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
436 rovr->tk_flags |= RPC_TASK_KILLED;
437 rpc_exit(rovr, -EIO);
438 rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr);
439 }
440 }
441 spin_unlock(&clnt->cl_lock);
442}
443EXPORT_SYMBOL_GPL(rpc_killall_tasks);
444
445/*
417 * Properly shut down an RPC client, terminating all outstanding 446 * Properly shut down an RPC client, terminating all outstanding
418 * requests. 447 * requests.
419 */ 448 */
@@ -538,6 +567,49 @@ out:
538} 567}
539EXPORT_SYMBOL_GPL(rpc_bind_new_program); 568EXPORT_SYMBOL_GPL(rpc_bind_new_program);
540 569
570void rpc_task_release_client(struct rpc_task *task)
571{
572 struct rpc_clnt *clnt = task->tk_client;
573
574 if (clnt != NULL) {
575 /* Remove from client task list */
576 spin_lock(&clnt->cl_lock);
577 list_del(&task->tk_task);
578 spin_unlock(&clnt->cl_lock);
579 task->tk_client = NULL;
580
581 rpc_release_client(clnt);
582 }
583}
584
585static
586void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
587{
588 if (clnt != NULL) {
589 rpc_task_release_client(task);
590 task->tk_client = clnt;
591 kref_get(&clnt->cl_kref);
592 if (clnt->cl_softrtry)
593 task->tk_flags |= RPC_TASK_SOFT;
594 /* Add to the client's list of all tasks */
595 spin_lock(&clnt->cl_lock);
596 list_add_tail(&task->tk_task, &clnt->cl_tasks);
597 spin_unlock(&clnt->cl_lock);
598 }
599}
600
601static void
602rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
603{
604 if (msg != NULL) {
605 task->tk_msg.rpc_proc = msg->rpc_proc;
606 task->tk_msg.rpc_argp = msg->rpc_argp;
607 task->tk_msg.rpc_resp = msg->rpc_resp;
608 if (msg->rpc_cred != NULL)
609 task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
610 }
611}
612
541/* 613/*
542 * Default callback for async RPC calls 614 * Default callback for async RPC calls
543 */ 615 */
@@ -562,6 +634,18 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
562 if (IS_ERR(task)) 634 if (IS_ERR(task))
563 goto out; 635 goto out;
564 636
637 rpc_task_set_client(task, task_setup_data->rpc_client);
638 rpc_task_set_rpc_message(task, task_setup_data->rpc_message);
639
640 if (task->tk_status != 0) {
641 int ret = task->tk_status;
642 rpc_put_task(task);
643 return ERR_PTR(ret);
644 }
645
646 if (task->tk_action == NULL)
647 rpc_call_start(task);
648
565 atomic_inc(&task->tk_count); 649 atomic_inc(&task->tk_count);
566 rpc_execute(task); 650 rpc_execute(task);
567out: 651out:
@@ -756,12 +840,13 @@ EXPORT_SYMBOL_GPL(rpc_force_rebind);
756 * Restart an (async) RPC call from the call_prepare state. 840 * Restart an (async) RPC call from the call_prepare state.
757 * Usually called from within the exit handler. 841 * Usually called from within the exit handler.
758 */ 842 */
759void 843int
760rpc_restart_call_prepare(struct rpc_task *task) 844rpc_restart_call_prepare(struct rpc_task *task)
761{ 845{
762 if (RPC_ASSASSINATED(task)) 846 if (RPC_ASSASSINATED(task))
763 return; 847 return 0;
764 task->tk_action = rpc_prepare_task; 848 task->tk_action = rpc_prepare_task;
849 return 1;
765} 850}
766EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); 851EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
767 852
@@ -769,13 +854,13 @@ EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
769 * Restart an (async) RPC call. Usually called from within the 854 * Restart an (async) RPC call. Usually called from within the
770 * exit handler. 855 * exit handler.
771 */ 856 */
772void 857int
773rpc_restart_call(struct rpc_task *task) 858rpc_restart_call(struct rpc_task *task)
774{ 859{
775 if (RPC_ASSASSINATED(task)) 860 if (RPC_ASSASSINATED(task))
776 return; 861 return 0;
777
778 task->tk_action = call_start; 862 task->tk_action = call_start;
863 return 1;
779} 864}
780EXPORT_SYMBOL_GPL(rpc_restart_call); 865EXPORT_SYMBOL_GPL(rpc_restart_call);
781 866
@@ -824,11 +909,6 @@ call_reserve(struct rpc_task *task)
824{ 909{
825 dprint_status(task); 910 dprint_status(task);
826 911
827 if (!rpcauth_uptodatecred(task)) {
828 task->tk_action = call_refresh;
829 return;
830 }
831
832 task->tk_status = 0; 912 task->tk_status = 0;
833 task->tk_action = call_reserveresult; 913 task->tk_action = call_reserveresult;
834 xprt_reserve(task); 914 xprt_reserve(task);
@@ -892,7 +972,7 @@ call_reserveresult(struct rpc_task *task)
892static void 972static void
893call_allocate(struct rpc_task *task) 973call_allocate(struct rpc_task *task)
894{ 974{
895 unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack; 975 unsigned int slack = task->tk_client->cl_auth->au_cslack;
896 struct rpc_rqst *req = task->tk_rqstp; 976 struct rpc_rqst *req = task->tk_rqstp;
897 struct rpc_xprt *xprt = task->tk_xprt; 977 struct rpc_xprt *xprt = task->tk_xprt;
898 struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 978 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -900,7 +980,7 @@ call_allocate(struct rpc_task *task)
900 dprint_status(task); 980 dprint_status(task);
901 981
902 task->tk_status = 0; 982 task->tk_status = 0;
903 task->tk_action = call_bind; 983 task->tk_action = call_refresh;
904 984
905 if (req->rq_buffer) 985 if (req->rq_buffer)
906 return; 986 return;
@@ -937,6 +1017,47 @@ call_allocate(struct rpc_task *task)
937 rpc_exit(task, -ERESTARTSYS); 1017 rpc_exit(task, -ERESTARTSYS);
938} 1018}
939 1019
1020/*
1021 * 2a. Bind and/or refresh the credentials
1022 */
1023static void
1024call_refresh(struct rpc_task *task)
1025{
1026 dprint_status(task);
1027
1028 task->tk_action = call_refreshresult;
1029 task->tk_status = 0;
1030 task->tk_client->cl_stats->rpcauthrefresh++;
1031 rpcauth_refreshcred(task);
1032}
1033
1034/*
1035 * 2b. Process the results of a credential refresh
1036 */
1037static void
1038call_refreshresult(struct rpc_task *task)
1039{
1040 int status = task->tk_status;
1041
1042 dprint_status(task);
1043
1044 task->tk_status = 0;
1045 task->tk_action = call_bind;
1046 if (status >= 0 && rpcauth_uptodatecred(task))
1047 return;
1048 switch (status) {
1049 case -EACCES:
1050 rpc_exit(task, -EACCES);
1051 return;
1052 case -ENOMEM:
1053 rpc_exit(task, -ENOMEM);
1054 return;
1055 case -ETIMEDOUT:
1056 rpc_delay(task, 3*HZ);
1057 }
1058 task->tk_action = call_refresh;
1059}
1060
940static inline int 1061static inline int
941rpc_task_need_encode(struct rpc_task *task) 1062rpc_task_need_encode(struct rpc_task *task)
942{ 1063{
@@ -1472,43 +1593,6 @@ out_retry:
1472 } 1593 }
1473} 1594}
1474 1595
1475/*
1476 * 8. Refresh the credentials if rejected by the server
1477 */
1478static void
1479call_refresh(struct rpc_task *task)
1480{
1481 dprint_status(task);
1482
1483 task->tk_action = call_refreshresult;
1484 task->tk_status = 0;
1485 task->tk_client->cl_stats->rpcauthrefresh++;
1486 rpcauth_refreshcred(task);
1487}
1488
1489/*
1490 * 8a. Process the results of a credential refresh
1491 */
1492static void
1493call_refreshresult(struct rpc_task *task)
1494{
1495 int status = task->tk_status;
1496
1497 dprint_status(task);
1498
1499 task->tk_status = 0;
1500 task->tk_action = call_reserve;
1501 if (status >= 0 && rpcauth_uptodatecred(task))
1502 return;
1503 if (status == -EACCES) {
1504 rpc_exit(task, -EACCES);
1505 return;
1506 }
1507 task->tk_action = call_refresh;
1508 if (status != -ETIMEDOUT)
1509 rpc_delay(task, 3*HZ);
1510}
1511
1512static __be32 * 1596static __be32 *
1513rpc_encode_header(struct rpc_task *task) 1597rpc_encode_header(struct rpc_task *task)
1514{ 1598{
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 4a843b883b89..cace6049e4a5 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -246,17 +246,8 @@ static inline void rpc_task_set_debuginfo(struct rpc_task *task)
246 246
247static void rpc_set_active(struct rpc_task *task) 247static void rpc_set_active(struct rpc_task *task)
248{ 248{
249 struct rpc_clnt *clnt;
250 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
251 return;
252 rpc_task_set_debuginfo(task); 249 rpc_task_set_debuginfo(task);
253 /* Add to global list of all tasks */ 250 set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
254 clnt = task->tk_client;
255 if (clnt != NULL) {
256 spin_lock(&clnt->cl_lock);
257 list_add_tail(&task->tk_task, &clnt->cl_tasks);
258 spin_unlock(&clnt->cl_lock);
259 }
260} 251}
261 252
262/* 253/*
@@ -319,11 +310,6 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
319 dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", 310 dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
320 task->tk_pid, rpc_qname(q), jiffies); 311 task->tk_pid, rpc_qname(q), jiffies);
321 312
322 if (!RPC_IS_ASYNC(task) && !RPC_IS_ACTIVATED(task)) {
323 printk(KERN_ERR "RPC: Inactive synchronous task put to sleep!\n");
324 return;
325 }
326
327 __rpc_add_wait_queue(q, task); 313 __rpc_add_wait_queue(q, task);
328 314
329 BUG_ON(task->tk_callback != NULL); 315 BUG_ON(task->tk_callback != NULL);
@@ -334,8 +320,8 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
334void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, 320void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
335 rpc_action action) 321 rpc_action action)
336{ 322{
337 /* Mark the task as being activated if so needed */ 323 /* We shouldn't ever put an inactive task to sleep */
338 rpc_set_active(task); 324 BUG_ON(!RPC_IS_ACTIVATED(task));
339 325
340 /* 326 /*
341 * Protect the queue operations. 327 * Protect the queue operations.
@@ -406,14 +392,6 @@ void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task
406EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task); 392EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task);
407 393
408/* 394/*
409 * Wake up the specified task
410 */
411static void rpc_wake_up_task(struct rpc_task *task)
412{
413 rpc_wake_up_queued_task(task->tk_waitqueue, task);
414}
415
416/*
417 * Wake up the next task on a priority queue. 395 * Wake up the next task on a priority queue.
418 */ 396 */
419static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queue) 397static struct rpc_task * __rpc_wake_up_next_priority(struct rpc_wait_queue *queue)
@@ -600,7 +578,15 @@ void rpc_exit_task(struct rpc_task *task)
600 } 578 }
601 } 579 }
602} 580}
603EXPORT_SYMBOL_GPL(rpc_exit_task); 581
582void rpc_exit(struct rpc_task *task, int status)
583{
584 task->tk_status = status;
585 task->tk_action = rpc_exit_task;
586 if (RPC_IS_QUEUED(task))
587 rpc_wake_up_queued_task(task->tk_waitqueue, task);
588}
589EXPORT_SYMBOL_GPL(rpc_exit);
604 590
605void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata) 591void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
606{ 592{
@@ -690,7 +676,6 @@ static void __rpc_execute(struct rpc_task *task)
690 dprintk("RPC: %5u got signal\n", task->tk_pid); 676 dprintk("RPC: %5u got signal\n", task->tk_pid);
691 task->tk_flags |= RPC_TASK_KILLED; 677 task->tk_flags |= RPC_TASK_KILLED;
692 rpc_exit(task, -ERESTARTSYS); 678 rpc_exit(task, -ERESTARTSYS);
693 rpc_wake_up_task(task);
694 } 679 }
695 rpc_set_running(task); 680 rpc_set_running(task);
696 dprintk("RPC: %5u sync task resuming\n", task->tk_pid); 681 dprintk("RPC: %5u sync task resuming\n", task->tk_pid);
@@ -714,8 +699,9 @@ static void __rpc_execute(struct rpc_task *task)
714void rpc_execute(struct rpc_task *task) 699void rpc_execute(struct rpc_task *task)
715{ 700{
716 rpc_set_active(task); 701 rpc_set_active(task);
717 rpc_set_running(task); 702 rpc_make_runnable(task);
718 __rpc_execute(task); 703 if (!RPC_IS_ASYNC(task))
704 __rpc_execute(task);
719} 705}
720 706
721static void rpc_async_schedule(struct work_struct *work) 707static void rpc_async_schedule(struct work_struct *work)
@@ -808,26 +794,9 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
808 /* Initialize workqueue for async tasks */ 794 /* Initialize workqueue for async tasks */
809 task->tk_workqueue = task_setup_data->workqueue; 795 task->tk_workqueue = task_setup_data->workqueue;
810 796
811 task->tk_client = task_setup_data->rpc_client;
812 if (task->tk_client != NULL) {
813 kref_get(&task->tk_client->cl_kref);
814 if (task->tk_client->cl_softrtry)
815 task->tk_flags |= RPC_TASK_SOFT;
816 }
817
818 if (task->tk_ops->rpc_call_prepare != NULL) 797 if (task->tk_ops->rpc_call_prepare != NULL)
819 task->tk_action = rpc_prepare_task; 798 task->tk_action = rpc_prepare_task;
820 799
821 if (task_setup_data->rpc_message != NULL) {
822 task->tk_msg.rpc_proc = task_setup_data->rpc_message->rpc_proc;
823 task->tk_msg.rpc_argp = task_setup_data->rpc_message->rpc_argp;
824 task->tk_msg.rpc_resp = task_setup_data->rpc_message->rpc_resp;
825 /* Bind the user cred */
826 rpcauth_bindcred(task, task_setup_data->rpc_message->rpc_cred, task_setup_data->flags);
827 if (task->tk_action == NULL)
828 rpc_call_start(task);
829 }
830
831 /* starting timestamp */ 800 /* starting timestamp */
832 task->tk_start = ktime_get(); 801 task->tk_start = ktime_get();
833 802
@@ -896,11 +865,8 @@ void rpc_put_task(struct rpc_task *task)
896 if (task->tk_rqstp) 865 if (task->tk_rqstp)
897 xprt_release(task); 866 xprt_release(task);
898 if (task->tk_msg.rpc_cred) 867 if (task->tk_msg.rpc_cred)
899 rpcauth_unbindcred(task); 868 put_rpccred(task->tk_msg.rpc_cred);
900 if (task->tk_client) { 869 rpc_task_release_client(task);
901 rpc_release_client(task->tk_client);
902 task->tk_client = NULL;
903 }
904 if (task->tk_workqueue != NULL) { 870 if (task->tk_workqueue != NULL) {
905 INIT_WORK(&task->u.tk_work, rpc_async_release); 871 INIT_WORK(&task->u.tk_work, rpc_async_release);
906 queue_work(task->tk_workqueue, &task->u.tk_work); 872 queue_work(task->tk_workqueue, &task->u.tk_work);
@@ -913,13 +879,6 @@ static void rpc_release_task(struct rpc_task *task)
913{ 879{
914 dprintk("RPC: %5u release task\n", task->tk_pid); 880 dprintk("RPC: %5u release task\n", task->tk_pid);
915 881
916 if (!list_empty(&task->tk_task)) {
917 struct rpc_clnt *clnt = task->tk_client;
918 /* Remove from client task list */
919 spin_lock(&clnt->cl_lock);
920 list_del(&task->tk_task);
921 spin_unlock(&clnt->cl_lock);
922 }
923 BUG_ON (RPC_IS_QUEUED(task)); 882 BUG_ON (RPC_IS_QUEUED(task));
924 883
925 /* Wake up anyone who is waiting for task completion */ 884 /* Wake up anyone who is waiting for task completion */
@@ -928,35 +887,6 @@ static void rpc_release_task(struct rpc_task *task)
928 rpc_put_task(task); 887 rpc_put_task(task);
929} 888}
930 889
931/*
932 * Kill all tasks for the given client.
933 * XXX: kill their descendants as well?
934 */
935void rpc_killall_tasks(struct rpc_clnt *clnt)
936{
937 struct rpc_task *rovr;
938
939
940 if (list_empty(&clnt->cl_tasks))
941 return;
942 dprintk("RPC: killing all tasks for client %p\n", clnt);
943 /*
944 * Spin lock all_tasks to prevent changes...
945 */
946 spin_lock(&clnt->cl_lock);
947 list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
948 if (! RPC_IS_ACTIVATED(rovr))
949 continue;
950 if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
951 rovr->tk_flags |= RPC_TASK_KILLED;
952 rpc_exit(rovr, -EIO);
953 rpc_wake_up_task(rovr);
954 }
955 }
956 spin_unlock(&clnt->cl_lock);
957}
958EXPORT_SYMBOL_GPL(rpc_killall_tasks);
959
960int rpciod_up(void) 890int rpciod_up(void)
961{ 891{
962 return try_module_get(THIS_MODULE) ? 0 : -EINVAL; 892 return try_module_get(THIS_MODULE) ? 0 : -EINVAL;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index f438347d817b..c0d085013a2b 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -33,21 +33,27 @@ init_sunrpc(void)
33 if (err) 33 if (err)
34 goto out; 34 goto out;
35 err = rpc_init_mempool(); 35 err = rpc_init_mempool();
36 if (err) { 36 if (err)
37 unregister_rpc_pipefs(); 37 goto out2;
38 goto out; 38 err = rpcauth_init_module();
39 } 39 if (err)
40 goto out3;
40#ifdef RPC_DEBUG 41#ifdef RPC_DEBUG
41 rpc_register_sysctl(); 42 rpc_register_sysctl();
42#endif 43#endif
43#ifdef CONFIG_PROC_FS 44#ifdef CONFIG_PROC_FS
44 rpc_proc_init(); 45 rpc_proc_init();
45#endif 46#endif
47 cache_initialize();
46 cache_register(&ip_map_cache); 48 cache_register(&ip_map_cache);
47 cache_register(&unix_gid_cache); 49 cache_register(&unix_gid_cache);
48 svc_init_xprt_sock(); /* svc sock transport */ 50 svc_init_xprt_sock(); /* svc sock transport */
49 init_socket_xprt(); /* clnt sock transport */ 51 init_socket_xprt(); /* clnt sock transport */
50 rpcauth_init_module(); 52 return 0;
53out3:
54 rpc_destroy_mempool();
55out2:
56 unregister_rpc_pipefs();
51out: 57out:
52 return err; 58 return err;
53} 59}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index dcd0132396ba..970fb00f388c 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -1032,6 +1032,8 @@ void xprt_release(struct rpc_task *task)
1032 spin_unlock_bh(&xprt->transport_lock); 1032 spin_unlock_bh(&xprt->transport_lock);
1033 if (req->rq_buffer) 1033 if (req->rq_buffer)
1034 xprt->ops->buf_free(req->rq_buffer); 1034 xprt->ops->buf_free(req->rq_buffer);
1035 if (req->rq_cred != NULL)
1036 put_rpccred(req->rq_cred);
1035 task->tk_rqstp = NULL; 1037 task->tk_rqstp = NULL;
1036 if (req->rq_release_snd_buf) 1038 if (req->rq_release_snd_buf)
1037 req->rq_release_snd_buf(req); 1039 req->rq_release_snd_buf(req);
@@ -1129,6 +1131,7 @@ static void xprt_destroy(struct kref *kref)
1129 rpc_destroy_wait_queue(&xprt->sending); 1131 rpc_destroy_wait_queue(&xprt->sending);
1130 rpc_destroy_wait_queue(&xprt->resend); 1132 rpc_destroy_wait_queue(&xprt->resend);
1131 rpc_destroy_wait_queue(&xprt->backlog); 1133 rpc_destroy_wait_queue(&xprt->backlog);
1134 cancel_work_sync(&xprt->task_cleanup);
1132 /* 1135 /*
1133 * Tear down transport state and free the rpc_xprt 1136 * Tear down transport state and free the rpc_xprt
1134 */ 1137 */