| .. | .. |
|---|
| 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) |
|---|