summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-05-03 13:26:55 -0400
committerDavid Howells <dhowells@redhat.com>2019-05-15 12:35:54 -0400
commitd0660f0b3b7d1760d1ab60ec8e9d0de52e885207 (patch)
tree9ab40b7b55492fbaeede2311afb643c5cadf2b75
parentca1cbbdce92bc2bfdc17e4f70ad41f6e6af2d03f (diff)
dns_resolver: Allow used keys to be invalidated
Allow used DNS resolver keys to be invalidated after use if the caller is doing its own caching of the results. This reduces the amount of resources required. Fix AFS to invalidate DNS results to kill off permanent failure records that get lodged in the resolver keyring and prevent future lookups from happening. Fixes: 0a5143f2f89c ("afs: Implement VL server rotation") Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--fs/afs/addr_list.c2
-rw-r--r--fs/afs/dynroot.c2
-rw-r--r--fs/cifs/dns_resolve.c2
-rw-r--r--fs/nfs/dns_resolve.c2
-rw-r--r--include/linux/dns_resolver.h3
-rw-r--r--net/ceph/messenger.c2
-rw-r--r--net/dns_resolver/dns_query.c6
7 files changed, 12 insertions, 7 deletions
diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c
index 967db336d11a..9eaff55df7b4 100644
--- a/fs/afs/addr_list.c
+++ b/fs/afs/addr_list.c
@@ -251,7 +251,7 @@ struct afs_vlserver_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry
251 _enter("%s", cell->name); 251 _enter("%s", cell->name);
252 252
253 ret = dns_query("afsdb", cell->name, cell->name_len, "srv=1", 253 ret = dns_query("afsdb", cell->name, cell->name_len, "srv=1",
254 &result, _expiry); 254 &result, _expiry, true);
255 if (ret < 0) { 255 if (ret < 0) {
256 _leave(" = %d [dns]", ret); 256 _leave(" = %d [dns]", ret);
257 return ERR_PTR(ret); 257 return ERR_PTR(ret);
diff --git a/fs/afs/dynroot.c b/fs/afs/dynroot.c
index a9ba81ddf154..07484b5a3bbb 100644
--- a/fs/afs/dynroot.c
+++ b/fs/afs/dynroot.c
@@ -46,7 +46,7 @@ static int afs_probe_cell_name(struct dentry *dentry)
46 return 0; 46 return 0;
47 } 47 }
48 48
49 ret = dns_query("afsdb", name, len, "srv=1", NULL, NULL); 49 ret = dns_query("afsdb", name, len, "srv=1", NULL, NULL, false);
50 if (ret == -ENODATA) 50 if (ret == -ENODATA)
51 ret = -EDESTADDRREQ; 51 ret = -EDESTADDRREQ;
52 return ret; 52 return ret;
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c
index 7ede7306599f..1e21b2528cfb 100644
--- a/fs/cifs/dns_resolve.c
+++ b/fs/cifs/dns_resolve.c
@@ -77,7 +77,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
77 goto name_is_IP_address; 77 goto name_is_IP_address;
78 78
79 /* Perform the upcall */ 79 /* Perform the upcall */
80 rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL); 80 rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL, false);
81 if (rc < 0) 81 if (rc < 0)
82 cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n", 82 cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
83 __func__, len, len, hostname); 83 __func__, len, len, hostname);
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index a7d3df85736d..e6a700f01452 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -22,7 +22,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
22 char *ip_addr = NULL; 22 char *ip_addr = NULL;
23 int ip_len; 23 int ip_len;
24 24
25 ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL); 25 ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL, false);
26 if (ip_len > 0) 26 if (ip_len > 0)
27 ret = rpc_pton(net, ip_addr, ip_len, sa, salen); 27 ret = rpc_pton(net, ip_addr, ip_len, sa, salen);
28 else 28 else
diff --git a/include/linux/dns_resolver.h b/include/linux/dns_resolver.h
index 34a744a1bafc..f2b3ae22e6b7 100644
--- a/include/linux/dns_resolver.h
+++ b/include/linux/dns_resolver.h
@@ -27,6 +27,7 @@
27#include <uapi/linux/dns_resolver.h> 27#include <uapi/linux/dns_resolver.h>
28 28
29extern int dns_query(const char *type, const char *name, size_t namelen, 29extern int dns_query(const char *type, const char *name, size_t namelen,
30 const char *options, char **_result, time64_t *_expiry); 30 const char *options, char **_result, time64_t *_expiry,
31 bool invalidate);
31 32
32#endif /* _LINUX_DNS_RESOLVER_H */ 33#endif /* _LINUX_DNS_RESOLVER_H */
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 3083988ce729..579d6a1ac7fe 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -1889,7 +1889,7 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen,
1889 return -EINVAL; 1889 return -EINVAL;
1890 1890
1891 /* do dns_resolve upcall */ 1891 /* do dns_resolve upcall */
1892 ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL); 1892 ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL, false);
1893 if (ip_len > 0) 1893 if (ip_len > 0)
1894 ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL); 1894 ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL);
1895 else 1895 else
diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
index 19aa32fc1802..2d260432b3be 100644
--- a/net/dns_resolver/dns_query.c
+++ b/net/dns_resolver/dns_query.c
@@ -54,6 +54,7 @@
54 * @options: Request options (or NULL if no options) 54 * @options: Request options (or NULL if no options)
55 * @_result: Where to place the returned data (or NULL) 55 * @_result: Where to place the returned data (or NULL)
56 * @_expiry: Where to store the result expiry time (or NULL) 56 * @_expiry: Where to store the result expiry time (or NULL)
57 * @invalidate: Always invalidate the key after use
57 * 58 *
58 * The data will be returned in the pointer at *result, if provided, and the 59 * The data will be returned in the pointer at *result, if provided, and the
59 * caller is responsible for freeing it. 60 * caller is responsible for freeing it.
@@ -69,7 +70,8 @@
69 * Returns the size of the result on success, -ve error code otherwise. 70 * Returns the size of the result on success, -ve error code otherwise.
70 */ 71 */
71int dns_query(const char *type, const char *name, size_t namelen, 72int dns_query(const char *type, const char *name, size_t namelen,
72 const char *options, char **_result, time64_t *_expiry) 73 const char *options, char **_result, time64_t *_expiry,
74 bool invalidate)
73{ 75{
74 struct key *rkey; 76 struct key *rkey;
75 struct user_key_payload *upayload; 77 struct user_key_payload *upayload;
@@ -157,6 +159,8 @@ int dns_query(const char *type, const char *name, size_t namelen,
157 ret = len; 159 ret = len;
158put: 160put:
159 up_read(&rkey->sem); 161 up_read(&rkey->sem);
162 if (invalidate)
163 key_invalidate(rkey);
160 key_put(rkey); 164 key_put(rkey);
161out: 165out:
162 kleave(" = %d", ret); 166 kleave(" = %d", ret);