From patchwork Thu Nov 15 14:21:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Aur=C3=A9lien_Aptel?= X-Patchwork-Id: 10684433 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EFFB2109C for ; Thu, 15 Nov 2018 14:22:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFA5B2C810 for ; Thu, 15 Nov 2018 14:22:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D38E62C820; Thu, 15 Nov 2018 14:22:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 61B342C810 for ; Thu, 15 Nov 2018 14:22:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732953AbeKPAao (ORCPT ); Thu, 15 Nov 2018 19:30:44 -0500 Received: from mx2.suse.de ([195.135.220.15]:42960 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729035AbeKPAao (ORCPT ); Thu, 15 Nov 2018 19:30:44 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 8FDCAAFF1; Thu, 15 Nov 2018 14:22:40 +0000 (UTC) From: Aurelien Aptel To: linux-cifs@vger.kernel.org Cc: smfrench@gmail.com, Paulo Alcantara , Paulo Alcantara , Aurelien Aptel Subject: [PATCH v1 14/14] cifs: Add support for failover in cifs_reconnect_tcon() Date: Thu, 15 Nov 2018 15:21:03 +0100 Message-Id: <20181115142103.24617-15-aaptel@suse.com> X-Mailer: git-send-email 2.13.7 In-Reply-To: <20181115142103.24617-1-aaptel@suse.com> References: <20181115142103.24617-1-aaptel@suse.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Paulo Alcantara After a successful failover, the cifs_reconnect_tcon() function will make sure to reconnect every tcon to new target server. Same as previous commit but for SMB1 codepath. Signed-off-by: Paulo Alcantara Signed-off-by: Aurelien Aptel --- fs/cifs/cifssmb.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f82fd342bca5..b1f49c1c543a 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -44,6 +44,9 @@ #include "cifs_debug.h" #include "fscache.h" #include "smbdirect.h" +#ifdef CONFIG_CIFS_DFS_UPCALL +#include "dfs_cache.h" +#endif #ifdef CONFIG_CIFS_POSIX static struct { @@ -118,6 +121,77 @@ 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 dfs_cache_tgt_list tl; + struct dfs_cache_tgt_iterator *it = NULL; + char tree[MAX_TREE_SIZE + 1]; + const char *tcp_host; + size_t tcp_host_len; + const char *dfs_host; + size_t dfs_host_len; + + if (tcon->ipc) { + snprintf(tree, sizeof(tree), "\\\\%s\\IPC$", + tcon->ses->server->hostname); + return CIFSTCon(0, tcon->ses, tree, tcon, nlsc); + } + + if (!tcon->dfs_path) + return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc); + + rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl); + if (rc) + return rc; + + extract_unc_hostname(tcon->ses->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 *tgt = dfs_cache_get_tgt_name(it); + + extract_unc_hostname(tgt, &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: skipping %.*s, doesn't match %.*s", + __func__, + (int)dfs_host_len, dfs_host, + (int)tcp_host_len, tcp_host); + continue; + } + + snprintf(tree, sizeof(tree), "\\%s", tgt); + + rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc); + if (!rc) + 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); + 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) @@ -126,6 +200,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) struct cifs_ses *ses; struct TCP_Server_Info *server; struct nls_table *nls_codepage; + int retries; /* * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for @@ -152,9 +227,12 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) } } + retries = server->nr_targets; + /* - * Give demultiplex thread up to 10 seconds to reconnect, should be - * greater than cifs socket timeout which is 7 seconds + * Give demultiplex thread up to 10 seconds to each target available for + * reconnect -- should be greater than cifs socket timeout which is 7 + * seconds. */ while (server->tcpStatus == CifsNeedReconnect) { rc = wait_event_interruptible_timeout(server->response_q, @@ -170,6 +248,9 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) if (server->tcpStatus != CifsNeedReconnect) break; + if (--retries) + continue; + /* * on "soft" mounts we wait once. Hard mounts keep * retrying until process is killed or server comes @@ -179,6 +260,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n"); return -EHOSTDOWN; } + retries = server->nr_targets; } if (!ses->need_reconnect && !tcon->need_reconnect) @@ -214,7 +296,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) } cifs_mark_open_files_invalid(tcon); - rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage); + rc = __cifs_reconnect_tcon(nls_codepage, tcon); mutex_unlock(&ses->session_mutex); cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);