From 7548e1da8d2d345debb9c0f141c47e4077d6085b Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 21 Jul 2020 09:36:42 -0300 Subject: cifs: handle RESP_GET_DFS_REFERRAL.PathConsumed in reconnect Use PathConsumed field when parsing prefixes of referral paths that either match a cache entry or are a complete prefix path of an existing entry. Signed-off-by: Paulo Alcantara (SUSE) Reviewed-by: Aurelien Aptel Signed-off-by: Steve French --- fs/cifs/connect.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'fs/cifs/connect.c') diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 78e6460d1e49..48b5133580d5 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -5547,6 +5547,7 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru size_t tcp_host_len; const char *dfs_host; size_t dfs_host_len; + char *share = NULL, *prefix = NULL; tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL); if (!tree) @@ -5569,11 +5570,12 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len); for (it = dfs_cache_get_tgt_iterator(&tl); it; it = dfs_cache_get_next_tgt(&tl, it)) { - const char *share, *prefix; - size_t share_len, prefix_len; bool target_match; - rc = dfs_cache_get_tgt_share(it, &share, &share_len, &prefix, &prefix_len); + kfree(share); + kfree(prefix); + + rc = dfs_cache_get_tgt_share(tcon->dfs_path + 1, it, &share, &prefix); if (rc) { cifs_dbg(VFS, "%s: failed to parse target share %d\n", __func__, rc); @@ -5600,13 +5602,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru } if (tcon->ipc) { - scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$", (int)share_len, share); + scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", share); rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); } else { - scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len, share); + scnprintf(tree, MAX_TREE_SIZE, "\\%s", share); rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc); if (!rc) { - rc = update_super_prepath(tcon, prefix, prefix_len); + rc = update_super_prepath(tcon, prefix); break; } } @@ -5614,6 +5616,9 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru break; } + kfree(share); + kfree(prefix); + if (!rc) { if (it) rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1, it); -- cgit v1.2.3