From patchwork Wed Nov 30 00:56:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovskiy X-Patchwork-Id: 9453485 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 71FBE60235 for ; Wed, 30 Nov 2016 02:29:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A39028173 for ; Wed, 30 Nov 2016 02:29:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4DD2A281A7; Wed, 30 Nov 2016 02:29:25 +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 60B4428173 for ; Wed, 30 Nov 2016 02:29:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754091AbcK3C3X (ORCPT ); Tue, 29 Nov 2016 21:29:23 -0500 Received: from mail-dm3nam03on0137.outbound.protection.outlook.com ([104.47.41.137]:61323 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751732AbcK3C3V (ORCPT ); Tue, 29 Nov 2016 21:29:21 -0500 X-Greylist: delayed 4623 seconds by postgrey-1.27 at vger.kernel.org; Tue, 29 Nov 2016 21:29:21 EST 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=Y0O33E466saHh7pmzasY+B+TYGQjH3uvchCUljsyFRQ=; b=mL0PL1Wq0nF2LUPhNglbgdRM+n4q8VekW1FhOoOGjagzszk4du8nP19FWtWpVBJPTAyfJ9s8wJy9sGgKabHJ62fK8UryxixAUp0uzytidOjyz58KAYZ+NavDp6GlU8ufGpRVNnn7XhDLT+wXEN+4AR288D5hSM+2LQbj6SHlZzA= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pshilov@microsoft.com; Received: from ubuntu-vm.corp.microsoft.com (2001:4898:80e8::63b) by BN6PR03MB2546.namprd03.prod.outlook.com (10.173.142.149) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.747.10; Wed, 30 Nov 2016 00:57:06 +0000 From: Pavel Shilovsky To: Subject: [PATCH 4/5] CIFS: Fix a possible memory corruption during reconnect Date: Tue, 29 Nov 2016 16:56:55 -0800 Message-ID: <1480467416-13636-5-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1480467416-13636-1-git-send-email-pshilov@microsoft.com> References: <1480467416-13636-1-git-send-email-pshilov@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8::63b] X-ClientProxiedBy: CY4PR08CA0032.namprd08.prod.outlook.com (10.173.247.146) To BN6PR03MB2546.namprd03.prod.outlook.com (10.173.142.149) X-MS-Office365-Filtering-Correlation-Id: 0e0d0590-ba22-42d1-a815-08d418bbce4b X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:BN6PR03MB2546; X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2546; 3:Y01Bs6+nXSug5bLt7EbDkt2ssuOiBSCukKDSJwwW03OKikBk/0OmPafDsgA1OxAmnacQn4aK7cxaAtIXAE0OrFg+O/3hzDBaI4UfD5xGQn1gEJW2VCwdG0tB+RD2rCBJN2GIX3L3E+qPuUefD4X3TMCjtofTop+LYJdOAQ6cllTVhRv2aU0UrawjlDTOHMwAZc7B5ABEdJUFABsil6XY2tBQ5gPXgc6vWrxqftmICGlIG6a2kZJTEJSGLvg2/pnXMseSgN89627Yvat3tGoMcw==; 25:gql6Olktlw+IKkUoMhxtbEeg77luP1zaSECqrjT/OSznRfRr+vaxpx9sEufbWa+Rwr9YzmXFsnBU9k+JUP0EyciNSVzL2es3wknCVxBA63XXbGjP601aSkqI41w1cDdeEfK1P7XGQsXyLSoXXO0qdthK+ztYrQb9sEPEImpmOvV3qqFg+2Al4ktue2txl2GagxSVlNKx2yRP2BxtTl3jjZkQCoj3fmBXaOlm4/A9MYGPPsxsSfj4OYXCCIk0N96/riA3FRmSvMfTwtAmTj8Y6jnpD0lvh5lcfBujD1gj6g5wbb3sDTwVhkSr4iELUvDCmNnWsYGM3FS0iCGvyzSj0oLCUMpAnD2AP7McSednlNlVd7lEoFxHoMX0qkmo4kQOYxucGch612TW58dBk2ahX/3q6Dw0smtwyCQnjugFQkeDU3N8odsk0B76+P6JGgEOwH/zSKLRBv1raEgTMCjdxg== X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2546; 31:mDKBI+D+WT5OjRICBgMRAOiXKBnu1+eFXwnA3aXuooZ8KRvJWziPsEeJBlAs7TND7f3xBKM3bNfyFmbG9NgBOsIZ+iVKO0hWdx1NgzMtEtI6FzMkf0p6PhBqk0nCuFWbSkeTiCU6nK4dVf3xAwDTHZYH4spWK+O32+LQDnWc7fnthmOhMlBNu2DLnAp47McUdzsyAnlyJvgEIyEgZGWdF6G3vZPL0+OcTIvMoH0kz0zyFgaYGhy/bTVLBhgaRsSKCQmNvkMCkfPVP72MafT5hhkNu/Y/0sBbZJwZEc9AoVc=; 20:pkL9v9GEJP1WE8fi1o0g4APYFkOQxFPMlhcyHzYKJOAvAB9lyh4SoK0gbutJFBV6SCjGYfFK//5bQZ9Y7C6k/krhOdsRwTeTOH8bOwKPNeXacf2o2uL+MuWNBDYFCQA8hhV0lJworL5YScgYcF+Iue/HT+6E3GF5j9NX3aTaDAmZC/j9p6X4arbaJ/hM5oC0mnYI7WaPlfwLQT7LHtTx1VsnwaM++/uI4M6wO2h5ysvOlr8wqy8HmCo3EFXaLlFJ7jHj2gp6tTw6F45qDuGU+mFrvrrPkjXB6Zm3HBVNvpq1eH17/Q1LX14KeogtBt6JPdYtat80JqTH0FbfDfD6OKPumhjEY62Ku3q6uSuCtUKNM+MfLo24D5z4xOk7ekCDBQBEUjGU8LVB3amuTUIvL+kEoXV06AN+yu6uq16WHUa71XVYVx4ytXve25kmhmigpsiAq97ep90cOAGUC5igQt1ONC0b5MTegNHBT3PJS/y16oQxCw61vtd89r94BpG1 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)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(20161123560025)(20161123558021)(20161123564025)(20161123562025)(20161123555025)(6072148)(6047074); SRVR:BN6PR03MB2546; BCL:0; PCL:0; RULEID:; SRVR:BN6PR03MB2546; X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2546; 4:639tcOBlaykKIDy/pJoB2RQcDZcnK0yWXG0DaLzT3waqtWE1RDk/uj+aa3F4PhZywQu0iUU12pQ3lKfV9SvYCxrtv/4QvNiu9fi8fCYv1yxjvO5xCjuY04EoFC+uBBZP99BvVNfb/SWFKiNHgqbnVd+JlBH6Oh5hpXv6LYbOy6PNIuSXcqG4z95JA4BfjMYn8Gumf3dbJ9Q249hOI//Q7McYPUw36fOz26cC547G7ZiXeYblXYsiFap5ANRKnNkXYovyfPJIy5+qGMLDMomGRjGyHRnxAQXZNAFe/xTQPNl00f1/bTRaszLIAK6LVZGTa37SU4wcsYGBwYSjn/ggM3C3oZXFt1XTHunVaaOGHjUHGMFgShen4IZ0lxKG8N9d3IfkG+n3el5mK/wUZJ6mN0eBlz9l9+ueL78Z8Tx+nX20u6mnGxU1GtLH8IB4tgL9dGSON2XKMeWyeF/W963PiYFFf2HCux0Ete2pVHvr6F7tgoBQbyl1JKIlGJR9RWakmBsAgaCx8vmPnHMM69pYI38FQ9mkOuRu+0e7gcBFeGdCMwuESyqlW8Ax6rAzZ9VsVhJPSLjanJ+GZKdz+aAOlnQq2Oi7orwCFIgjCHr//382N0hGRlJP9WmDZR/vCN67+nGpOieZk2T3O8oVFkIFRBnMnvUpjVgjFE6gip1/5tpS3bcpbQXcXUkcpBbdbR1sT3cAlEwUm6InexUtWePgsA8Tfj4YAxahHK8xvdWLXLk= X-Forefront-PRVS: 0142F22657 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(199003)(189002)(69234005)(6486002)(2351001)(450100001)(5005710100001)(733004)(5660300001)(50226002)(50466002)(81156014)(81166006)(7736002)(8676002)(7846002)(39450400002)(5003940100001)(36756003)(107886002)(10290500002)(110136003)(39410400001)(42186005)(86612001)(68736007)(105586002)(6116002)(6916009)(575784001)(33646002)(101416001)(2950100002)(189998001)(106356001)(305945005)(92566002)(38730400001)(6666003)(2906002)(50986999)(97736004)(48376002)(47776003)(10090500001)(76176999)(86362001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN6PR03MB2546; H:ubuntu-vm.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX: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; BN6PR03MB2546; 23:sqFFyzjhjtgSyyT07ck3X59yjqtoVohK9j83Pc2w9?= =?us-ascii?Q?E3FmFM6djqG9bLr5p1Bp+WnuhVQ7sQsH4zVCYE7UUXrjAZEDRqlqxjWbhmIf?= =?us-ascii?Q?zWO8wooJ+QbLNdJZpc1mbJkC6lgEWJDVHT6cblwnDJP6s3yDUEur+y7Msg88?= =?us-ascii?Q?4zm0yjbDdosKAxCBBz9vTTnyPNX+Eaw5hkT16boYXkidDz4wmZDbNzdFD46W?= =?us-ascii?Q?9XTh/KkiUU81+ZywL613ovl6U1BuiFGSxRkM2aXiCoHbUowyF0hpStwssdOP?= =?us-ascii?Q?FDeAR+Ntya1YeQX+9EMLwU0jQDM5YAdRL0AefMTSt5UiTwXCtzwaDtWsQL+t?= =?us-ascii?Q?pxj8jvpleYyuDXdyCXuvCpijNqWtmBEGXidEzpMWJeL4hS1sgmytfjtVij7I?= =?us-ascii?Q?pvVwzdVTyp0JlszwjVkG2uK91BBOChSPzP+Nrj1mkKmuUDFk0mtDMA+gipyI?= =?us-ascii?Q?laRzhh5xs92+SiuiRDwQPf7zZuakYovk/Agm6JZFFEEKEyK3KK2ln9wuwVck?= =?us-ascii?Q?5tRHV5Thmx5nC14PL5NnG4Gqeyn+TsedhhhW6+HX96XEjM3yTtbU6ya4+ttl?= =?us-ascii?Q?Njotcp+w041ZJeVWRGbjKqoz/HoF21vYNGW8iqKlxpE0zZjMV/6DoJ242WxL?= =?us-ascii?Q?66PPx70HBDdmNdnaSsV8yPcsGojmRZFRerTXONwWlLRDwLNBNyQz7Rx7xR4F?= =?us-ascii?Q?x6WMSaraW9oFJGtqL9/k/p/e06se3kw3TnoBvSTTv1HQRyGw1H3qJYE9WR9V?= =?us-ascii?Q?+a0pTFgp+DcRwHwYy8rkiZPaa1HyTNd5sOsc0V0RXu5Lng35uAkystVPmY9G?= =?us-ascii?Q?Kjh5hTjcI429HYW84LtZccdxTlfY8AjgP8foQazGDWa9rMpl9ullyBt7ujdS?= =?us-ascii?Q?pyLlgEMy+xzFik0RU4qrbW+EFx1EBz9Ll1ja0/ET0X4ue8k9vAMsl4s/gT2M?= =?us-ascii?Q?1uAL/yzbQqjnd0+lz4Dtwq634iXTD/xcIbtv5+oJQGxjgjLna51sPA3PtP4z?= =?us-ascii?Q?IguCYJSEKzfENdFlNoW0TC1nyWAixquqbm1qqu9w7ut5WHImY7UQ3JDnq/4M?= =?us-ascii?Q?CVuyfkQpMyri21+8hJ/8LAfGr2NO0yaD7plrPloKkzGxvJUGSa0YmBLBy4hR?= =?us-ascii?Q?+SsQCTNyJGFPKHXJcDd0i15gBrbVVdO7CGobmI2JsbKPZyUfzDBcSV4qMUhU?= =?us-ascii?Q?Dc+SyskmENqKKyStuzQ1AGgzqrSAj0mBYFXT+F28+Q4Zuj6pp2XZqnd+uOUZ?= =?us-ascii?Q?CtNcpa2WStS0NXZ/n8=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2546; 6:vKBozqChJEiAwZ6yzwx+aM4PqjijnzLzbAYrXGDjBGdb77/FOAJVfj37Avy2Gb7Evknue/bO906bF90DrcbnUPjNUBfKCFoI20y/Pd+N5XSmL4olzgtTLquaUbtQc2QYl7xvZoh9X89imtL9+pIZ/hhbwNm+EdBsZJ2dZj7jM42KDJdd77lRYxbb4nqVjZ5oem9WF2H1obuByGFTQ22+AopNbIZ2MZIGUpKqy+CmpVR8gh6eeFqKuy2TwddRmP3Pn7O5tKKzSJ1u+YEncpoGlVv/NG+Yh3pewmtPj6lRPtnn7DNJmQyIqSrIEfCTAF0I4z4s6WoJUF3/7QWyvtAxZ/lp+z06abUTq3NKxHJ5w7yYSPkq8AFElgxLKIF/ZX0cxQA488UmUYnH5qQEyRT2dxVPoxp09UuHFNqPFTLMCXA+p0YGuc/UHCNVKSA2OxlaeK6e3l7bELknc5sspOl/iaTf9FasTs45UipUyE5C+Jg=; 5:yia8eVY4Zl6yJnKk2t3KGD5V196jB5k/WbDCYZq54TaFmSLOewOeIwwWBLgBcWfOQs1y5Emd7mtxtLLmdeRe/w8fnk5UWZbxnYQ/eMqi0sgWAJYx9BEnv5QbNVd7BhXp7v6rGx/qd+HAF4bgoACg2o6FPb30pBrJupLJPHXKyf0=; 24:fg/7EM5E1ou7FUgAtE8gFdyuwI3NCSxMpqd3YLDSyRpIi4MWjIRF5xh1W6xs1Sc/JivjH9bYo7/AsB8nmTz7YBMb7G3T67AJRFNgMoWcyUc= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BN6PR03MB2546; 7:2PSZpxFgyyXy9ydB7GR6KobzSZD9zsXqv228VJS5QHrkuPBYWBXu5gibnkJGLAI+ugHspPSTRyJBXAqfGw3L2q1WWyfvFNEbjOmCoOJ9JIQeMX0WFQnuaEkNQJxVDGmwh/Yv54xZJlFa1wEFUKVILWSJetcTC7TCuv8eLvL8trQuD4Gj43Y6gi6Qr4M1dLj+tGs4qhjkEmH62n1tcB06/iYsJQ+xb7YW+lF2EwNqg56OBMQPvz5WXJA/AtEufN63M7n8xmRROCSwCREyZWjlBy8eVsJstH2jRuoVD7L0wiEaL7aF9Jeaqiys9Ub1g/0c518UwhcRjtJ1d6D1fGIrNX07J3Y9ZGQXrA84ccOGCNYhlS7bfL7ctrS9P91oscFEIRNHuAlFxUXoaHz6uSjN3VWLX9eKH/YkfcnBMBB8D5etR3cqwYDc5Wetk0NGGKPEFAruImCHzjWtIP9K59AOPQ== X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Nov 2016 00:57:06.2726 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR03MB2546 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 --- 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 1f17f6b..52368a6 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -646,6 +646,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 @@ struct cifs_tcon { struct list_head tcon_list; int tc_count; struct list_head openFileList; + struct list_head rlist; /* reconnect list */ spinlock_t open_file_lock; /* protects list above */ struct cifs_ses *ses; /* pointer to session associated with */ char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ 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 4547aed..893be07 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 @@ -2100,8 +2103,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; @@ -2118,6 +2121,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); @@ -2182,6 +2198,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, @@ -2340,7 +2360,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 @@ -2514,7 +2534,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; } @@ -2604,7 +2624,7 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc) return NULL; } -static void +void cifs_put_tcon(struct cifs_tcon *tcon) { unsigned int xid; @@ -3792,7 +3812,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); } @@ -4103,7 +4123,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..8fecf4b 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 */ + mod_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