.. | .. |
---|
22 | 22 | char *ip_addr = NULL; |
---|
23 | 23 | int ip_len; |
---|
24 | 24 | |
---|
25 | | - ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL); |
---|
| 25 | + ip_len = dns_query(net, NULL, name, namelen, NULL, &ip_addr, NULL, |
---|
| 26 | + false); |
---|
26 | 27 | if (ip_len > 0) |
---|
27 | 28 | ret = rpc_pton(net, ip_addr, ip_len, sa, salen); |
---|
28 | 29 | else |
---|
.. | .. |
---|
38 | 39 | #include <linux/string.h> |
---|
39 | 40 | #include <linux/kmod.h> |
---|
40 | 41 | #include <linux/slab.h> |
---|
41 | | -#include <linux/module.h> |
---|
42 | 42 | #include <linux/socket.h> |
---|
43 | 43 | #include <linux/seq_file.h> |
---|
44 | 44 | #include <linux/inet.h> |
---|
.. | .. |
---|
65 | 65 | |
---|
66 | 66 | struct sockaddr_storage addr; |
---|
67 | 67 | size_t addrlen; |
---|
| 68 | + struct rcu_head rcu_head; |
---|
68 | 69 | }; |
---|
69 | 70 | |
---|
70 | 71 | |
---|
.. | .. |
---|
91 | 92 | key = container_of(ckey, struct nfs_dns_ent, h); |
---|
92 | 93 | |
---|
93 | 94 | kfree(new->hostname); |
---|
94 | | - new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL); |
---|
| 95 | + new->hostname = kmemdup_nul(key->hostname, key->namelen, GFP_KERNEL); |
---|
95 | 96 | if (new->hostname) { |
---|
96 | 97 | new->namelen = key->namelen; |
---|
97 | 98 | nfs_dns_ent_update(cnew, ckey); |
---|
.. | .. |
---|
101 | 102 | } |
---|
102 | 103 | } |
---|
103 | 104 | |
---|
| 105 | +static void nfs_dns_ent_free_rcu(struct rcu_head *head) |
---|
| 106 | +{ |
---|
| 107 | + struct nfs_dns_ent *item; |
---|
| 108 | + |
---|
| 109 | + item = container_of(head, struct nfs_dns_ent, rcu_head); |
---|
| 110 | + kfree(item->hostname); |
---|
| 111 | + kfree(item); |
---|
| 112 | +} |
---|
| 113 | + |
---|
104 | 114 | static void nfs_dns_ent_put(struct kref *ref) |
---|
105 | 115 | { |
---|
106 | 116 | struct nfs_dns_ent *item; |
---|
107 | 117 | |
---|
108 | 118 | item = container_of(ref, struct nfs_dns_ent, h.ref); |
---|
109 | | - kfree(item->hostname); |
---|
110 | | - kfree(item); |
---|
| 119 | + call_rcu(&item->rcu_head, nfs_dns_ent_free_rcu); |
---|
111 | 120 | } |
---|
112 | 121 | |
---|
113 | 122 | static struct cache_head *nfs_dns_ent_alloc(void) |
---|
.. | .. |
---|
142 | 151 | struct cache_head *ch) |
---|
143 | 152 | { |
---|
144 | 153 | struct nfs_dns_ent *key = container_of(ch, struct nfs_dns_ent, h); |
---|
145 | | - int ret; |
---|
146 | 154 | |
---|
147 | | - ret = nfs_cache_upcall(cd, key->hostname); |
---|
148 | | - if (ret) |
---|
149 | | - ret = sunrpc_cache_pipe_upcall(cd, ch); |
---|
150 | | - return ret; |
---|
| 155 | + if (test_and_set_bit(CACHE_PENDING, &ch->flags)) |
---|
| 156 | + return 0; |
---|
| 157 | + if (!nfs_cache_upcall(cd, key->hostname)) |
---|
| 158 | + return 0; |
---|
| 159 | + clear_bit(CACHE_PENDING, &ch->flags); |
---|
| 160 | + return sunrpc_cache_pipe_upcall_timeout(cd, ch); |
---|
151 | 161 | } |
---|
152 | 162 | |
---|
153 | 163 | static int nfs_dns_match(struct cache_head *ca, |
---|
.. | .. |
---|
195 | 205 | { |
---|
196 | 206 | struct cache_head *ch; |
---|
197 | 207 | |
---|
198 | | - ch = sunrpc_cache_lookup(cd, |
---|
| 208 | + ch = sunrpc_cache_lookup_rcu(cd, |
---|
199 | 209 | &key->h, |
---|
200 | 210 | nfs_dns_hash(key)); |
---|
201 | 211 | if (!ch) |
---|