Commit d0660f0b authored by David Howells's avatar David Howells

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: 0a5143f2 ("afs: Implement VL server rotation")
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent ca1cbbdc
...@@ -251,7 +251,7 @@ struct afs_vlserver_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry ...@@ -251,7 +251,7 @@ struct afs_vlserver_list *afs_dns_query(struct afs_cell *cell, time64_t *_expiry
_enter("%s", cell->name); _enter("%s", cell->name);
ret = dns_query("afsdb", cell->name, cell->name_len, "srv=1", ret = dns_query("afsdb", cell->name, cell->name_len, "srv=1",
&result, _expiry); &result, _expiry, true);
if (ret < 0) { if (ret < 0) {
_leave(" = %d [dns]", ret); _leave(" = %d [dns]", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -46,7 +46,7 @@ static int afs_probe_cell_name(struct dentry *dentry) ...@@ -46,7 +46,7 @@ static int afs_probe_cell_name(struct dentry *dentry)
return 0; return 0;
} }
ret = dns_query("afsdb", name, len, "srv=1", NULL, NULL); ret = dns_query("afsdb", name, len, "srv=1", NULL, NULL, false);
if (ret == -ENODATA) if (ret == -ENODATA)
ret = -EDESTADDRREQ; ret = -EDESTADDRREQ;
return ret; return ret;
......
...@@ -77,7 +77,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) ...@@ -77,7 +77,7 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
goto name_is_IP_address; goto name_is_IP_address;
/* Perform the upcall */ /* Perform the upcall */
rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL); rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL, false);
if (rc < 0) if (rc < 0)
cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n", cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
__func__, len, len, hostname); __func__, len, len, hostname);
......
...@@ -22,7 +22,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen, ...@@ -22,7 +22,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
char *ip_addr = NULL; char *ip_addr = NULL;
int ip_len; int ip_len;
ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL); ip_len = dns_query(NULL, name, namelen, NULL, &ip_addr, NULL, false);
if (ip_len > 0) if (ip_len > 0)
ret = rpc_pton(net, ip_addr, ip_len, sa, salen); ret = rpc_pton(net, ip_addr, ip_len, sa, salen);
else else
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <uapi/linux/dns_resolver.h> #include <uapi/linux/dns_resolver.h>
extern int dns_query(const char *type, const char *name, size_t namelen, extern int dns_query(const char *type, const char *name, size_t namelen,
const char *options, char **_result, time64_t *_expiry); const char *options, char **_result, time64_t *_expiry,
bool invalidate);
#endif /* _LINUX_DNS_RESOLVER_H */ #endif /* _LINUX_DNS_RESOLVER_H */
...@@ -1889,7 +1889,7 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen, ...@@ -1889,7 +1889,7 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen,
return -EINVAL; return -EINVAL;
/* do dns_resolve upcall */ /* do dns_resolve upcall */
ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL); ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL, false);
if (ip_len > 0) if (ip_len > 0)
ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL); ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL);
else else
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
* @options: Request options (or NULL if no options) * @options: Request options (or NULL if no options)
* @_result: Where to place the returned data (or NULL) * @_result: Where to place the returned data (or NULL)
* @_expiry: Where to store the result expiry time (or NULL) * @_expiry: Where to store the result expiry time (or NULL)
* @invalidate: Always invalidate the key after use
* *
* The data will be returned in the pointer at *result, if provided, and the * The data will be returned in the pointer at *result, if provided, and the
* caller is responsible for freeing it. * caller is responsible for freeing it.
...@@ -69,7 +70,8 @@ ...@@ -69,7 +70,8 @@
* Returns the size of the result on success, -ve error code otherwise. * Returns the size of the result on success, -ve error code otherwise.
*/ */
int dns_query(const char *type, const char *name, size_t namelen, int dns_query(const char *type, const char *name, size_t namelen,
const char *options, char **_result, time64_t *_expiry) const char *options, char **_result, time64_t *_expiry,
bool invalidate)
{ {
struct key *rkey; struct key *rkey;
struct user_key_payload *upayload; struct user_key_payload *upayload;
...@@ -157,6 +159,8 @@ int dns_query(const char *type, const char *name, size_t namelen, ...@@ -157,6 +159,8 @@ int dns_query(const char *type, const char *name, size_t namelen,
ret = len; ret = len;
put: put:
up_read(&rkey->sem); up_read(&rkey->sem);
if (invalidate)
key_invalidate(rkey);
key_put(rkey); key_put(rkey);
out: out:
kleave(" = %d", ret); kleave(" = %d", ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment