cifs: merge __{cifs,smb2}_reconnect[_tcon]() into cifs_tree_connect()
They were identical execpt to CIFSTCon() vs. SMB2_tcon(). These are also available via ops->tree_connect(). Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
1a0e7f7c3c
commit
565674d613
|
@ -272,6 +272,9 @@ extern void cifs_move_llist(struct list_head *source, struct list_head *dest);
|
|||
extern void cifs_free_llist(struct list_head *llist);
|
||||
extern void cifs_del_lock_waiters(struct cifsLockInfo *lock);
|
||||
|
||||
extern int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
const struct nls_table *nlsc);
|
||||
|
||||
extern int cifs_negotiate_protocol(const unsigned int xid,
|
||||
struct cifs_ses *ses);
|
||||
extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
|
||||
|
|
|
@ -124,116 +124,6 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
|
|||
*/
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
|
||||
struct cifs_tcon *tcon)
|
||||
{
|
||||
int rc;
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
struct dfs_cache_tgt_list tl;
|
||||
struct dfs_cache_tgt_iterator *it = NULL;
|
||||
char *tree;
|
||||
const char *tcp_host;
|
||||
size_t tcp_host_len;
|
||||
const char *dfs_host;
|
||||
size_t dfs_host_len;
|
||||
|
||||
tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
|
||||
if (!tree)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!tcon->dfs_path) {
|
||||
if (tcon->ipc) {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
|
||||
server->hostname);
|
||||
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
|
||||
} else {
|
||||
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: failed to parse target share %d\n",
|
||||
__func__, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
extract_unc_hostname(share, &dfs_host, &dfs_host_len);
|
||||
|
||||
if (dfs_host_len != tcp_host_len
|
||||
|| strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
|
||||
cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n",
|
||||
__func__,
|
||||
(int)dfs_host_len, dfs_host,
|
||||
(int)tcp_host_len, tcp_host);
|
||||
|
||||
rc = match_target_ip(server, dfs_host, dfs_host_len,
|
||||
&target_match);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: failed to match target ip: %d\n",
|
||||
__func__, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!target_match) {
|
||||
cifs_dbg(FYI, "%s: skipping target\n", __func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (tcon->ipc) {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$",
|
||||
(int)share_len, share);
|
||||
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
|
||||
} else {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len,
|
||||
share);
|
||||
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
|
||||
if (!rc) {
|
||||
rc = update_super_prepath(tcon, prefix,
|
||||
prefix_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc == -EREMOTE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
if (it)
|
||||
rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
|
||||
it);
|
||||
else
|
||||
rc = -ENOENT;
|
||||
}
|
||||
dfs_cache_free_tgts(&tl);
|
||||
out:
|
||||
kfree(tree);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static inline int __cifs_reconnect_tcon(const struct nls_table *nlsc,
|
||||
struct cifs_tcon *tcon)
|
||||
{
|
||||
return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* reconnect the socket, tcon, and smb session if needed */
|
||||
static int
|
||||
cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
|
||||
|
@ -338,7 +228,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
|
|||
}
|
||||
|
||||
cifs_mark_open_files_invalid(tcon);
|
||||
rc = __cifs_reconnect_tcon(nls_codepage, tcon);
|
||||
rc = cifs_tree_connect(0, tcon, nls_codepage);
|
||||
mutex_unlock(&ses->session_mutex);
|
||||
cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
|
||||
|
||||
|
|
|
@ -5532,3 +5532,103 @@ cifs_prune_tlinks(struct work_struct *work)
|
|||
queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
|
||||
TLINK_IDLE_EXPIRE);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc)
|
||||
{
|
||||
int rc;
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
const struct smb_version_operations *ops = server->ops;
|
||||
struct dfs_cache_tgt_list tl;
|
||||
struct dfs_cache_tgt_iterator *it = NULL;
|
||||
char *tree;
|
||||
const char *tcp_host;
|
||||
size_t tcp_host_len;
|
||||
const char *dfs_host;
|
||||
size_t dfs_host_len;
|
||||
|
||||
tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
|
||||
if (!tree)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!tcon->dfs_path) {
|
||||
if (tcon->ipc) {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname);
|
||||
rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
|
||||
} else {
|
||||
rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: failed to parse target share %d\n",
|
||||
__func__, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
extract_unc_hostname(share, &dfs_host, &dfs_host_len);
|
||||
|
||||
if (dfs_host_len != tcp_host_len
|
||||
|| strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
|
||||
cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n", __func__, (int)dfs_host_len,
|
||||
dfs_host, (int)tcp_host_len, tcp_host);
|
||||
|
||||
rc = match_target_ip(server, dfs_host, dfs_host_len, &target_match);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: failed to match target ip: %d\n", __func__, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!target_match) {
|
||||
cifs_dbg(FYI, "%s: skipping target\n", __func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (tcon->ipc) {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$", (int)share_len, share);
|
||||
rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
|
||||
} else {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len, share);
|
||||
rc = ops->tree_connect(xid, tcon->ses, tree, tcon, nlsc);
|
||||
if (!rc) {
|
||||
rc = update_super_prepath(tcon, prefix, prefix_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc == -EREMOTE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
if (it)
|
||||
rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1, it);
|
||||
else
|
||||
rc = -ENOENT;
|
||||
}
|
||||
dfs_cache_free_tgts(&tl);
|
||||
out:
|
||||
kfree(tree);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc)
|
||||
{
|
||||
const struct smb_version_operations *ops = tcon->ses->server->ops;
|
||||
|
||||
return ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -152,117 +152,6 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd,
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
static int __smb2_reconnect(const struct nls_table *nlsc,
|
||||
struct cifs_tcon *tcon)
|
||||
{
|
||||
int rc;
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
struct dfs_cache_tgt_list tl;
|
||||
struct dfs_cache_tgt_iterator *it = NULL;
|
||||
char *tree;
|
||||
const char *tcp_host;
|
||||
size_t tcp_host_len;
|
||||
const char *dfs_host;
|
||||
size_t dfs_host_len;
|
||||
|
||||
tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
|
||||
if (!tree)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!tcon->dfs_path) {
|
||||
if (tcon->ipc) {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
|
||||
server->hostname);
|
||||
rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
|
||||
} else {
|
||||
rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon,
|
||||
nlsc);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
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);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: failed to parse target share %d\n",
|
||||
__func__, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
extract_unc_hostname(share, &dfs_host, &dfs_host_len);
|
||||
|
||||
if (dfs_host_len != tcp_host_len
|
||||
|| strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
|
||||
cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n",
|
||||
__func__,
|
||||
(int)dfs_host_len, dfs_host,
|
||||
(int)tcp_host_len, tcp_host);
|
||||
|
||||
rc = match_target_ip(server, dfs_host, dfs_host_len,
|
||||
&target_match);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "%s: failed to match target ip: %d\n",
|
||||
__func__, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!target_match) {
|
||||
cifs_dbg(FYI, "%s: skipping target\n", __func__);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (tcon->ipc) {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$",
|
||||
(int)share_len, share);
|
||||
rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
|
||||
} else {
|
||||
scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len,
|
||||
share);
|
||||
rc = SMB2_tcon(0, tcon->ses, tree, tcon, nlsc);
|
||||
if (!rc) {
|
||||
rc = update_super_prepath(tcon, prefix,
|
||||
prefix_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc == -EREMOTE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
if (it)
|
||||
rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
|
||||
it);
|
||||
else
|
||||
rc = -ENOENT;
|
||||
}
|
||||
dfs_cache_free_tgts(&tl);
|
||||
out:
|
||||
kfree(tree);
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
static inline int __smb2_reconnect(const struct nls_table *nlsc,
|
||||
struct cifs_tcon *tcon)
|
||||
{
|
||||
return SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nlsc);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
|
||||
struct TCP_Server_Info *server)
|
||||
|
@ -409,7 +298,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
|
|||
if (tcon->use_persistent)
|
||||
tcon->need_reopen_files = true;
|
||||
|
||||
rc = __smb2_reconnect(nls_codepage, tcon);
|
||||
rc = cifs_tree_connect(0, tcon, nls_codepage);
|
||||
mutex_unlock(&tcon->ses->session_mutex);
|
||||
|
||||
cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
|
||||
|
|
Loading…
Reference in New Issue