diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-21 10:40:08 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-21 10:40:08 -0800 |
commit | 0a924817d2ed9396401e0557c6134276d2e26382 (patch) | |
tree | 13846c9d2bc381a5dc1b08ffb513884ecf6e8e94 /fs/cifs/dns_resolve.c | |
parent | 6022ec6ee2c3a16b26f218d7abb538afb839bd6d (diff) | |
parent | aacfc939cc42293fbcfe113040b4e8abaef68429 (diff) |
Merge tag '6.2-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French:
"cifs/smb3 client fixes, mostly related to reconnect and/or DFS:
- two important reconnect fixes: cases where status of recently
connected IPCs and shares were not being updated leaving them in an
incorrect state
- fix for older Windows servers that would return
STATUS_OBJECT_NAME_INVALID to query info requests on DFS links in a
namespace that contained non-ASCII characters, reducing number of
wasted roundtrips.
- fix for leaked -ENOMEM to userspace when cifs.ko couldn't perform
I/O due to a disconnected server, expired or deleted session.
- removal of all unneeded DFS related mount option string parsing
(now using fs_context for automounts)
- improve clarity/readability, moving various DFS related functions
out of fs/cifs/connect.c (which was getting too big to be readable)
to new file.
- Fix problem when large number of DFS connections. Allow sharing of
DFS connections and fix how the referral paths are matched
- Referral caching fix: Instead of looking up ipc connections to
refresh cached referrals, store direct dfs root server's IPC
pointer in new sessions so it can simply be accessed to either
refresh or create a new referral that such connections belong to.
- Fix to allow dfs root server's connections to also failover
- Optimized reconnect of nested DFS links
- Set correct status of IPC connections marked for reconnect"
* tag '6.2-rc-smb3-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6:
cifs: update internal module number
cifs: don't leak -ENOMEM in smb2_open_file()
cifs: use origin fullpath for automounts
cifs: set correct status of tcon ipc when reconnecting
cifs: optimize reconnect of nested links
cifs: fix source pathname comparison of dfs supers
cifs: fix confusing debug message
cifs: don't block in dfs_cache_noreq_update_tgthint()
cifs: refresh root referrals
cifs: fix refresh of cached referrals
cifs: don't refresh cached referrals from unactive mounts
cifs: share dfs connections and supers
cifs: split out ses and tcon retrieval from mount_get_conns()
cifs: set resolved ip in sockaddr
cifs: remove unused smb3_fs_context::mount_options
cifs: get rid of mount options string parsing
cifs: use fs_context for automounts
cifs: reduce roundtrips on create/qinfo requests
cifs: set correct ipc status after initial tree connect
cifs: set correct tcon status after initial tree connect
Diffstat (limited to 'fs/cifs/dns_resolve.c')
-rw-r--r-- | fs/cifs/dns_resolve.c | 49 |
1 files changed, 24 insertions, 25 deletions
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index 0458d28d71aa..8bf8978bc5d6 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c @@ -12,6 +12,7 @@ * */ +#include <linux/inet.h> #include <linux/slab.h> #include <linux/dns_resolver.h> #include "dns_resolve.h" @@ -25,17 +26,13 @@ * @ip_addr: Where to return the IP address. * @expiry: Where to return the expiry time for the dns record. * - * The IP address will be returned in string form, and the caller is - * responsible for freeing it. - * - * Returns length of result on success, -ve on error. + * Returns zero success, -ve on error. */ int -dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry) +dns_resolve_server_name_to_ip(const char *unc, struct sockaddr *ip_addr, time64_t *expiry) { - struct sockaddr_storage ss; const char *hostname, *sep; - char *name; + char *ip; int len, rc; if (!ip_addr || !unc) @@ -60,30 +57,32 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr, time64_t *expiry) __func__, unc); /* Try to interpret hostname as an IPv4 or IPv6 address */ - rc = cifs_convert_address((struct sockaddr *)&ss, hostname, len); - if (rc > 0) - goto name_is_IP_address; + rc = cifs_convert_address(ip_addr, hostname, len); + if (rc > 0) { + cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %*.*s\n", __func__, len, len, + hostname); + return 0; + } /* Perform the upcall */ rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len, - NULL, ip_addr, expiry, false); - if (rc < 0) + NULL, &ip, expiry, false); + if (rc < 0) { cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n", __func__, len, len, hostname); - else + } else { cifs_dbg(FYI, "%s: resolved: %*.*s to %s expiry %llu\n", - __func__, len, len, hostname, *ip_addr, + __func__, len, len, hostname, ip, expiry ? (*expiry) : 0); - return rc; -name_is_IP_address: - name = kmalloc(len + 1, GFP_KERNEL); - if (!name) - return -ENOMEM; - memcpy(name, hostname, len); - name[len] = 0; - cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %s\n", - __func__, name); - *ip_addr = name; - return 0; + rc = cifs_convert_address(ip_addr, ip, strlen(ip)); + kfree(ip); + + if (!rc) { + cifs_dbg(FYI, "%s: unable to determine ip address\n", __func__); + rc = -EHOSTUNREACH; + } else + rc = 0; + } + return rc; } |