From patchwork Mon Dec 5 21:11:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovskiy X-Patchwork-Id: 9461507 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4CBAC60231 for ; Mon, 5 Dec 2016 21:11:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43AC52807B for ; Mon, 5 Dec 2016 21:11:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3744B28066; Mon, 5 Dec 2016 21:11:53 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 7A18828066 for ; Mon, 5 Dec 2016 21:11:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752273AbcLEVLw (ORCPT ); Mon, 5 Dec 2016 16:11:52 -0500 Received: from mail-by2nam01on0102.outbound.protection.outlook.com ([104.47.34.102]:50720 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752300AbcLEVLu (ORCPT ); Mon, 5 Dec 2016 16:11:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Rj2cSyLqiIMr+Q1RPxdWlYpTUzG/2Rmn6mrca5hvBLA=; b=hvPIVyGs7YTA/kii5Tt5G2htWQNuk1U/1BJzoQ6dbNsYcGABFrCyyw3VWHtn9Wk9bfWGSnK6BnbMazUIC0r54aHtdQIQ+aWT4MEail9HnXMEzROMpt4yTI9IpxTqK7i5A67FrXFNjflVhUwFiuIDSULTzEDdvYv9osgMi+w4QPw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pshilov@microsoft.com; Received: from ubuntu-vm.corp.microsoft.com (2001:4898:80e8:a::63b) by MWHPR03MB2557.namprd03.prod.outlook.com (10.168.206.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.747.13; Mon, 5 Dec 2016 21:11:41 +0000 From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH v2 4/5] CIFS: Fix a possible memory corruption during reconnect Date: Mon, 5 Dec 2016 13:11:10 -0800 Message-Id: <1480972271-57692-5-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1480972271-57692-1-git-send-email-pshilov@microsoft.com> References: <1480972271-57692-1-git-send-email-pshilov@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:a::63b] X-ClientProxiedBy: BY2PR06CA0069.namprd06.prod.outlook.com (10.166.106.165) To MWHPR03MB2557.namprd03.prod.outlook.com (10.168.206.19) X-MS-Office365-Filtering-Correlation-Id: b438493a-680b-47ee-bb5a-08d41d534f13 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:MWHPR03MB2557; X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2557; 3:s2yoHQMoj9UclroJQ1Z3sY4F4FWIG2Ypa7Wy8j+65bynVkFCsHNx6mWjbW5m45gbjXhnaq9DjhLygU/o0RfBE1dABL4zt2CqZNBVzwHlJz+mzLIWH4C7KBqfdJ/UHUj3nP5oAtX48cCBDYl52Ydi5HdjmCaVMC9xaGVNR+tojwP1Xzv8AAOaK3HFpPfcQT+nCQlsxDQthA6K57wVpQ91oaVlut/eqpmSDvDcGjQJjpxg5QXFvDKFE1HfeOcoN6dfirctKsEEzPIA5k2Oqzhx9g==; 25:40e6wtBxfV6eF7mdwPuNG6WuG4PMGqzG7NScoVSbhYDH1w+msFFmxXCCVC8tKmqzG2k7mcI1hNC8V6/mIlz1AR5VlbibHDZU4cGgG2RoFF7jE6Wfb3ULRzEom10ljRFRg26zMTC4tOQXhxYtMf9Ry6L1J4Em3lHpyKCVNL2zHnX5qTdzMWSGIzxWKFgNPYju9FrdISaXtSj5ZFXx82xgDswG7avzPgjgepSxPQXNCP5T2YvZOBCLHbhcA7iHiPchk9fsekgzNO1f3VIE2CXKMNiV+q92PZ3tu3p051ynbwiWsSm10njhcoi3FisLvt+AHOZxdJoveduzmDLlFN2LOSInxHGnNiSDf5Sx46yMzb3ZytAEWZ0TtUgp6hetH+SQrGu78bYlkH8n4zszV2KJvkqTsAmjXgJcJP3iju/w3IE8rCE2uK8uSO93moz9x29TkCDmVm1q9z1q0F5sR06alg== X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2557; 31:4ZSoVx9e6wmq3tPVNMoAMfp8IJmGSeec+jQTzdOubtLf04WVbUhf1W2V7kNqNCWHv0k3RQT48jZcNsZhGzMEAMV9udbCNQlUPsRtCMgYapiDXBWxxU1E1bZXxxfLQD6jx5W3jU5BiCcokSqP7Ahng0xbz1/xkZBn9JRpJfQdbXiQcfhwRcFL7pZrwx3ywezRouqXnYd6xd3U8nH0dcS4WusdH4/Z4jfh9Dd7pyaErUUbkN+syvJWLYqWP3Vy9UDxlxK9PU7Wduc0EhHmpXhA5w==; 20:/ENtyxhmZ+srGUznfLvp0TPydqp8lVgqZ+DJEkt04EF7wkuyf3+YUGxRUsNI/gtDCaGUmLac+f1DWrIQeUtJQokLtPqF9VYEdT/nlC2E1fPTaNU5ElgpPvh7jjjR9+RhdZlFWjGB+B05i8ljvffufBrtP/Th0Nc45dsNxr3rSPkoOK/qEC74QNDJ8At+Uhzk/X3I1Q5PCf2MeAPzjkWgidzlcfC+COvxKpQ5sbiVRrDhnGC4mOIK/4M+XU/w4ilrcuEwmf+02vCS8SXjbAF/+2EHDxbqaDhg/kSAKKNVE30IO8QkM2TIlfD/8ioYw4E0TgRJ4b7E75VMkOHnUfVRvq2xNM+eARqN47S1DpV2RYJxN7TKDKkDWN+lm4+hxUsYPFwHsOARzoFWpD3TPFgwu/eo1vzdnNJzn6lpPmi3BvZEF4f+eAA8hBkwBijMDINjb6ETI+qOxqsHWH0tKQ0Iu82zvYRrJiBT0N1Tk2WSzHqC6eHAZQyqJfmiaR4RTUYN X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(158342451672863)(9452136761055); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026)(6041248)(20161123558021)(20161123562025)(20161123564025)(20161123560025)(20161123555025)(6047074)(6072148); SRVR:MWHPR03MB2557; BCL:0; PCL:0; RULEID:; SRVR:MWHPR03MB2557; X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2557; 4:dovPPH4wy0yL9db/tks38thGXnFIDxZobdH0/ExP/7BfRskb0YMHEhWtYRFtRIykpe2Erp90vAlA6N8v5UFLebbH8buQ3GpEBBtptIFXn1zdTWk42HHZ0ixwGyD6gTmiM8e/TRx7glAT5ULLylIFjbhnrbppIN/9G9hUkInwr9fWQ7PQheUGpn5rkNKhtauwugecAFvgHuoVZJ2lZ+mjgX+WrvIXt1DXhk3VjuBQpQnzG+0eKxmHN5+X+dMu5Vp/CxXs7oKW/QCwSIZVbkl+J2FIo9FezXH1R7WsxTYMqxVdQerF6i1oKfcAvv+8alZ0khcshAlHNVETEPTQACmIwbGBNNfxeoveoZ78y+Dx3TcEg3r8P1va0EDsVlH1l5MkyC+WWcDEh5zXi60B8rbBE+ZTJa0OmDDd6YX20kTgtIIENv294OG5xt0BCqfDcjoZzrgk0HCU+X7GmxTEsXPq9WeMKqI00Nm3LufytKTCnRS3LRFQw+MTYnePsHB5GVS9uuofVirP5f5Bn+1AXuEvIl+JpgO7V5LgPIr1YE+IZx1lSupkLFCBpLx00KrI/JlHXpvtHKoIyhLaXY6isesjX26Y+hWRhMusJllFADJ5/ApkHL3UdgX/zDaFYt7DNV7mfPbJU+hcs2jUvtFvm2UCYHf7HNdgZMir/8IhDAXBtlk2j8elNXCW+fSJuKxY1T3SJeXEMD0pRcpgk40Fnn/Xdg== X-Forefront-PRVS: 0147E151B5 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(189002)(199003)(69234005)(5003940100001)(36756003)(5005710100001)(10290500002)(6116002)(92566002)(450100001)(42186005)(47776003)(5660300001)(105586002)(50986999)(76176999)(68736007)(33646002)(106356001)(39450400002)(50226002)(107886002)(189998001)(10090500001)(2906002)(39850400001)(39840400001)(38730400001)(39860400001)(733004)(8676002)(6486002)(81166006)(2361001)(39410400001)(81156014)(86362001)(305945005)(6916009)(2351001)(48376002)(86612001)(575784001)(97736004)(101416001)(7736002)(6666003)(7846002)(2950100002)(110136003)(50466002); DIR:OUT; SFP:1102; SCL:1; SRVR:MWHPR03MB2557; H:ubuntu-vm.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; MWHPR03MB2557; 23:QUMpf6LYzmS0wVJdtmntBKhyI1OiCRQwZMgne20nb?= =?us-ascii?Q?AwnBQXj5eKa7+XwerEFpw5oTpu/cnWfjp0ICeS8RaC8kAzn5jhIAGrastFP+?= =?us-ascii?Q?Jk12KoF3Q/ZjFznAoKllCORHsR72ddSLdKt497ZV4PVHOhff5Lor7ARQqpOP?= =?us-ascii?Q?kSJJ31XIlptqYy5Z/jCxx/IBDGT0qECB1Eqtk6A7Jrd2VgE7ERMvbDcLmcpk?= =?us-ascii?Q?gwYHaOQ89JaR3xBQgVw95CM0lEPPnq+JOWzMuGd9brBsmF8gISPQVoeWVW+w?= =?us-ascii?Q?3frJpxbfRpb9tNfSSOx9TAVMAKRKw43ue0FzVJhqmyysoES80vxjg8+g29GA?= =?us-ascii?Q?GZEmEeh385gY82dx2gYjtAE1df7ruYfOi8wH6Sbqpza94xm6XXNWUzdJd30B?= =?us-ascii?Q?3R3cmBUDyFBmX/+CRknwyZtuCHlersA2lwvjuVjUY2RoufaMizL++i456Xos?= =?us-ascii?Q?Ey1FTV6JGGjYnPnMCdcwLo33a9CIZ2KExEal1ndu3Hhwn6vU9Os0z8tiHLF+?= =?us-ascii?Q?vEWo7W3udUCYqdZApAPUQsYQ0i5v+ZDNjwjguWPoboWnXAyx3dp9Ci8IsON7?= =?us-ascii?Q?Rvf1LKTZ6HwkPtjb4f7lE8IjcJpbG7Uhr+YUaVMT3PPsyhFOZ7WLU2BYTx12?= =?us-ascii?Q?ZyVCUTn0xKcNiVPNQBOSX4ObHaLzoxeSi99lGwPRKmNp/Gv7GOrev3ce8QZG?= =?us-ascii?Q?sdiVOdxGTkdkKJnbgYo/sTFAXzrZqWsUZfDc4unfHunNOVpypwvz69tyTyjR?= =?us-ascii?Q?2S720IbeCupx3JVi7rUZLXj2Aq+gHtTAwtaaRLSwiLNkGbi4KHHL50Cus4Ea?= =?us-ascii?Q?HZfcPIE8YkprI0amIWHu8aWFbNxmru2fDDTGjbVd6OX8iWbzEk2MOQwsc54C?= =?us-ascii?Q?yOYHxUcNFI2Of4rHegPDFfbf6k6xq5oTmM4B5du/XQmrnOyYJnFy8A4MPtsU?= =?us-ascii?Q?Nnu7Pr+h1vuRFv9TobmJSBK1kDmDjIMRvRFJUkk+5ocUVESDfdebKmq7S1He?= =?us-ascii?Q?4Cm3rhMUKowvtC8/6b4cLU5LyOWhSmP/lArFLl31K4D9T13lzT/ppX6gEjtp?= =?us-ascii?Q?cwT4ISl/Aj9x4F0cX/cNMh/Jf/KynKKaVfi3wW6LduUlKlHPTUJOEI29pSv6?= =?us-ascii?Q?bk2zL95z+OQI2MarJ7fDevwW+IET/4qptgI6L3hB5kGaLqbrTZDxCEjgElVu?= =?us-ascii?Q?SFcDx9YSOIt6zHeM2Jvjlxoxi9RSKv1cS80JKHic5T4y+K8fv1rYMNvjQ8zP?= =?us-ascii?Q?21ZVa7oEDAgp+gD6vYj4bBKN750iybZ/BX1dZBQLH+mkzYCCc+WmIuu7eLQD?= =?us-ascii?Q?XqyifnCRoywDHgNZK1pksXB0ydRu+xYQ3cPUCac0h0r?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2557; 6:WqWPQrODEink7fzCN7Jt2sQHy5zmFvOMvAf87Uh0zvAoA+pmZMEVX1tNl05BBSRsAKnBJpLfhE6YFepMYGtleeGjzeR2YCWcerAgcKfSTXNLWbPYhcctKVD9KjymUv7mcWXJbGvQHuQtHCFe38fZIZfv6DB66+5QCT1+tO8XKlQD1fPkBWWk+hCwCm5DjOsfQrwzT7xgXQ64NCsRMbWaNsRg23ToBdzmBBJj5EW2slOA+LcKHDoAXMA3sl9g2lMnbwfwRZPMYS7bhQv3kFircpVMKK95b8c/NjMAgYJ49QH0W+kVnwotYBmWBMs2p1/i5f8PHWbSJVZWUgsCLccq+bw1BRj4Ust+vKv5kCXZ2FA0lnFYPsa3Yyq+kYaMMZp+sj7p6mAspj4ICa+wdCf75M4Z6bX7EjPQ77WRyG8+qOAHBFt2jnDSCINLdccwm/kgtw0f7fFzp9ChSd8rlCEhMwq+5z/oMXHNSXEGqRRZvW0=; 5:bOYn/wkiV2dkz5nPrFA4QFBACr449FudepiWp3oDFWTdJnttLK+ddf75PqtOD+2jZ7ksplHmg/aWqplLZQsWpo+S8+F3cjDzZomyAbRKh5fZwR30NPaDbWkptLD1swopcXUhomHaBS58IjDxUi84MA==; 24:ByCsEeS8B7/DSKaQCtZP6SBF/DtHcideSRMdikauHesTEyWrnC8DD16RqBQ8i9NK1sg28EHdnN4a6nIEmjSEmisBeEM5z4dqao/024gW98k= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; MWHPR03MB2557; 7:mOaoR9lK1QigoKVBaOBDgxeQfkuGUUhh38y2d/19I46MrBsRQVUehu9IgYzf7aS3631y8AH8mb7AbduRcJTGYldH5GjyGevuGBjlX6XNt+ngiqHCUt3lQf38UIL6eyubc92r08S3KQPtJyojBaE2l925Y7+xr2JueDZ8Tg7sISEXKGM8u2xiwW0MWNdPSBYPgIjLWBaH2YYN2pneK+jvwjHy2OAgiZsnMof9ZJslscJAa+0c2ID6hBXdO3EEfVJDbs62UY++JIvuew70vpsd1AdCEIrFauTiKZXLp1Db5LNbDcJorJ1MRjfgOBZho1eIfwEQe5O+R0O4KBW5AVG1csqlXWMoDPjH71RStafoKszzOwOqdjHWPRxPeEcb1AIbQP4RsmuAYHxTsdzMQszouaklnsZbU8heLi01FtiE43ZdUW2oEC/yGGwsXD7V7D6d+YyE6VW45FdzRdF1DkEg+Q== X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Dec 2016 21:11:41.0965 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR03MB2557 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 We can not unlock/lock cifs_tcp_ses_lock while walking through ses and tcon lists because it can corrupt list iterator pointers and a tcon structure can be released if we don't hold an extra reference. Fix it by moving a reconnect process to a separate delayed work and acquiring a reference to every tcon that needs to be reconnected. Also do not send an echo request on newly established connections. CC: Stable Signed-off-by: Pavel Shilovsky Acked-by: Sachin Prabhu --- fs/cifs/cifsglob.h | 3 +++ fs/cifs/cifsproto.h | 3 +++ fs/cifs/connect.c | 34 +++++++++++++++++++----- fs/cifs/smb2pdu.c | 75 ++++++++++++++++++++++++++++++++++++----------------- fs/cifs/smb2proto.h | 1 + 5 files changed, 85 insertions(+), 31 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 3e95191..89a0d7f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -647,6 +647,8 @@ struct TCP_Server_Info { unsigned int max_read; unsigned int max_write; __u8 preauth_hash[512]; + struct delayed_work reconnect; /* reconnect workqueue job */ + struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ #endif /* CONFIG_CIFS_SMB2 */ unsigned long echo_interval; }; @@ -850,6 +852,7 @@ cap_unix(struct cifs_ses *ses) struct cifs_tcon { struct list_head tcon_list; int tc_count; + struct list_head rlist; /* reconnect list */ struct list_head openFileList; spinlock_t open_file_lock; /* protects list above */ struct cifs_ses *ses; /* pointer to session associated with */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ced0e42..cd8025a 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -206,6 +206,9 @@ extern void cifs_add_pending_open_locked(struct cifs_fid *fid, struct tcon_link *tlink, struct cifs_pending_open *open); extern void cifs_del_pending_open(struct cifs_pending_open *open); +extern void cifs_put_tcp_session(struct TCP_Server_Info *server, + int from_reconnect); +extern void cifs_put_tcon(struct cifs_tcon *tcon); #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) extern void cifs_dfs_release_automount_timer(void); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 5563de3..5aaf7b1 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -52,6 +52,9 @@ #include "nterr.h" #include "rfc1002pdu.h" #include "fscache.h" +#ifdef CONFIG_CIFS_SMB2 +#include "smb2proto.h" +#endif #define CIFS_PORT 445 #define RFC1001_PORT 139 @@ -2110,8 +2113,8 @@ cifs_find_tcp_session(struct smb_vol *vol) return NULL; } -static void -cifs_put_tcp_session(struct TCP_Server_Info *server) +void +cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) { struct task_struct *task; @@ -2128,6 +2131,19 @@ cifs_put_tcp_session(struct TCP_Server_Info *server) cancel_delayed_work_sync(&server->echo); +#ifdef CONFIG_CIFS_SMB2 + if (from_reconnect) + /* + * Avoid deadlock here: reconnect work calls + * cifs_put_tcp_session() at its end. Need to be sure + * that reconnect work does nothing with server pointer after + * that step. + */ + cancel_delayed_work(&server->reconnect); + else + cancel_delayed_work_sync(&server->reconnect); +#endif + spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; spin_unlock(&GlobalMid_Lock); @@ -2192,6 +2208,10 @@ cifs_get_tcp_session(struct smb_vol *volume_info) INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); +#ifdef CONFIG_CIFS_SMB2 + INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); + mutex_init(&tcp_ses->reconnect_mutex); +#endif memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, sizeof(tcp_ses->srcaddr)); memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, @@ -2350,7 +2370,7 @@ cifs_put_smb_ses(struct cifs_ses *ses) spin_unlock(&cifs_tcp_ses_lock); sesInfoFree(ses); - cifs_put_tcp_session(server); + cifs_put_tcp_session(server, 0); } #ifdef CONFIG_KEYS @@ -2524,7 +2544,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) mutex_unlock(&ses->session_mutex); /* existing SMB ses has a server reference already */ - cifs_put_tcp_session(server); + cifs_put_tcp_session(server, 0); free_xid(xid); return ses; } @@ -2620,7 +2640,7 @@ cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) return NULL; } -static void +void cifs_put_tcon(struct cifs_tcon *tcon) { unsigned int xid; @@ -3824,7 +3844,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) else if (ses) cifs_put_smb_ses(ses); else - cifs_put_tcp_session(server); + cifs_put_tcp_session(server, 0); bdi_destroy(&cifs_sb->bdi); } @@ -4135,7 +4155,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); if (IS_ERR(ses)) { tcon = (struct cifs_tcon *)ses; - cifs_put_tcp_session(master_tcon->ses->server); + cifs_put_tcp_session(master_tcon->ses->server, 0); goto out; } diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 730d57b..4ba3f68 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1972,6 +1972,54 @@ smb2_echo_callback(struct mid_q_entry *mid) add_credits(server, credits_received, CIFS_ECHO_OP); } +void smb2_reconnect_server(struct work_struct *work) +{ + struct TCP_Server_Info *server = container_of(work, + struct TCP_Server_Info, reconnect.work); + struct cifs_ses *ses; + struct cifs_tcon *tcon, *tcon2; + struct list_head tmp_list; + int tcon_exist = false; + + /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */ + mutex_lock(&server->reconnect_mutex); + + INIT_LIST_HEAD(&tmp_list); + cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); + + spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { + if (tcon->need_reconnect) { + tcon->tc_count++; + list_add_tail(&tcon->rlist, &tmp_list); + tcon_exist = true; + } + } + } + /* + * Get the reference to server struct to be sure that the last call of + * cifs_put_tcon() in the loop below won't release the server pointer. + */ + if (tcon_exist) + server->srv_count++; + + spin_unlock(&cifs_tcp_ses_lock); + + list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { + smb2_reconnect(SMB2_ECHO, tcon); + list_del_init(&tcon->rlist); + cifs_put_tcon(tcon); + } + + cifs_dbg(FYI, "Reconnecting tcons finished\n"); + mutex_unlock(&server->reconnect_mutex); + + /* now we can safely release srv struct */ + if (tcon_exist) + cifs_put_tcp_session(server, 1); +} + int SMB2_echo(struct TCP_Server_Info *server) { @@ -1984,32 +2032,11 @@ SMB2_echo(struct TCP_Server_Info *server) cifs_dbg(FYI, "In echo request\n"); if (server->tcpStatus == CifsNeedNegotiate) { - struct list_head *tmp, *tmp2; - struct cifs_ses *ses; - struct cifs_tcon *tcon; - - cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); - spin_lock(&cifs_tcp_ses_lock); - list_for_each(tmp, &server->smb_ses_list) { - ses = list_entry(tmp, struct cifs_ses, smb_ses_list); - list_for_each(tmp2, &ses->tcon_list) { - tcon = list_entry(tmp2, struct cifs_tcon, - tcon_list); - /* add check for persistent handle reconnect */ - if (tcon && tcon->need_reconnect) { - spin_unlock(&cifs_tcp_ses_lock); - rc = smb2_reconnect(SMB2_ECHO, tcon); - spin_lock(&cifs_tcp_ses_lock); - } - } - } - spin_unlock(&cifs_tcp_ses_lock); + /* No need to send echo on newly established connections */ + queue_delayed_work(cifsiod_wq, &server->reconnect, 0); + return rc; } - /* if no session, renegotiate failed above */ - if (server->tcpStatus == CifsNeedNegotiate) - return -EIO; - rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req); if (rc) return rc; diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index eb2cde2..f2d511a 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h @@ -96,6 +96,7 @@ extern int smb2_open_file(const unsigned int xid, extern int smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, const unsigned int xid); extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); +extern void smb2_reconnect_server(struct work_struct *work); /* * SMB2 Worker functions - most of protocol specific implementation details