From patchwork Fri Jan 14 21:19:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 12714025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C9128C433F5 for ; Fri, 14 Jan 2022 21:19:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229805AbiANVTx (ORCPT ); Fri, 14 Jan 2022 16:19:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229795AbiANVTx (ORCPT ); Fri, 14 Jan 2022 16:19:53 -0500 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [IPv6:2a00:1450:4864:20::12a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2C23C061574 for ; Fri, 14 Jan 2022 13:19:52 -0800 (PST) Received: by mail-lf1-x12a.google.com with SMTP id d3so34160335lfv.13 for ; Fri, 14 Jan 2022 13:19:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:from:date:message-id:subject:to:cc; bh=XKFb6Fl53s2qi21kACRlDeG+z3DnemzG4XQNsK5L4EI=; b=oX2e8X3OD8k5DSjcYZVM9VVrYHNapKdBODXhf3evcm1vZpHW4XLAv44rjqsOZl3Aba aaXiV078vHiQ8WXC990fmTxq4+O0yeqGuOESsqowJtcXuIEkgr30tLcwze7uzX4RpVHd vH8nNtB3B7+oO92qvl4CMdsYsDrWcT0AZyCyne4qf5DcztmsVbK0sM6ou94B0mYKgeOi 3ANe8UiWM50U2lUK0bbQRRBMajg7uJAXtEFOuC/Xti8tl8vgVOl9vL/dkw5awkNVWng+ hYVuJ9YbSpW8OxQo4qCJabDacelkQSmath37OePuU+aOp1iKrHUjmCuYU2PrBmZ1HyeJ 6yTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=XKFb6Fl53s2qi21kACRlDeG+z3DnemzG4XQNsK5L4EI=; b=hlYdZ6s6Y7wzO7iNNfa/+HNi+2G5ebSdxVwBgdxlEED84L1x1hUDWmz6+XFK5BSAEH 2p7oixQMcu/ZILVTsKSRmBX+BNXymvfj6A7Tt1y60lPlwao2hXCQ+v7BuNklxWeHfJLw 12jtCep9zR8lFdcCfgRIXrrwJubQxfvSJ8/K2uUQARh7/nlTEBJeJkSY77C6dSHmtm8C kMwGfH6Iyeuvhhr7GuKFLiGemBB4/sXHzknEuJMn5Tmo7SSALViE+mHQF66ykTvsHI77 2F5a+IGxqnkKD+rVadfn9Za3Hz07cX3K7JMQ24K9fGT2DjJTlxbjMpm/zLEDiDM86PcZ X8RA== X-Gm-Message-State: AOAM532ftDRtMW4vltxotBta24D1NKiS+XU9IWej23zINqqvav5DuYR6 lJQFlGKIjv4FJQrxirQzIRNvHj5swAoC3vI8jtKpQcQKOWE= X-Google-Smtp-Source: ABdhPJxwcOKZIUK3kFFkd2ZEziVoRn65Pd6Kn0YxyEILI+0dh5FfBOEkDs2klszOujByHr3/so5JZTiF+PAvLQQ2BVA= X-Received: by 2002:a05:6512:3090:: with SMTP id z16mr1740181lfd.601.1642195190928; Fri, 14 Jan 2022 13:19:50 -0800 (PST) MIME-Version: 1.0 From: Steve French Date: Fri, 14 Jan 2022 15:19:39 -0600 Message-ID: Subject: Multichannel patch series reconnect bug To: Shyam Prasad N Cc: Paulo Alcantara , Enzo Matsumiya , CIFS Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org I have narrowed down the multichannel patch series bug which causes a few of the DFS regression tests to fail. Looks like it is in this part of the patch cifs-check-reconnects-for-channels-of-active-tcons-t.patch scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); @@ -4433,11 +4447,18 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru kfree(tree); cifs_put_tcp_super(sb); + if (rc) { + spin_lock(&cifs_tcp_ses_lock); + tcon->tidStatus = CifsNeedTcon; + spin_unlock(&cifs_tcp_ses_lock); + } + return rc; } #else int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) { + int rc; const struct smb_version_operations *ops = tcon->ses->server->ops; /* only send once per connect */ @@ -4451,6 +4472,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru tcon->tidStatus = CifsInTcon; spin_unlock(&cifs_tcp_ses_lock); - return ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); + rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); + if (rc) { + spin_lock(&cifs_tcp_ses_lock); + tcon->tidStatus = CifsNeedTcon; + spin_unlock(&cifs_tcp_ses_lock); + } + + return rc; } #endif diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f88d2b10045a..4c2048a8e464 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -119,6 +119,7 @@ enum statusEnum { CifsInSessSetup, CifsNeedTcon, CifsInTcon, + CifsNeedFilesInvalidate, CifsInFilesInvalidate }; @@ -925,6 +926,7 @@ struct cifs_chan { */ struct cifs_ses { struct list_head smb_ses_list; + struct list_head rlist; /* reconnect list */ struct list_head tcon_list; struct cifs_tcon *tcon_ipc; struct mutex session_mutex; diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 1dafaf7c4e5e..128c71b48002 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -335,6 +335,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server, spin_unlock(&cifs_tcp_ses_lock); cifs_swn_reset_server_dstaddr(server); mutex_unlock(&server->srv_mutex); + mod_delayed_work(cifsiod_wq, &server->reconnect, 0); } } while (server->tcpStatus == CifsNeedReconnect); @@ -4399,9 +4400,22 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru char *tree; struct dfs_info3_param ref = {0}; + /* only send once per connect */ + spin_lock(&cifs_tcp_ses_lock); + if (tcon->ses->status != CifsGood || + (tcon->tidStatus != CifsNew && + tcon->tidStatus != CifsNeedTcon)) { + spin_unlock(&cifs_tcp_ses_lock); + return 0; + } + tcon->tidStatus = CifsInTcon; + spin_unlock(&cifs_tcp_ses_lock); + tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL); - if (!tree) - return -ENOMEM; + if (!tree) { + rc = -ENOMEM; + goto out; + } if (tcon->ipc) { scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$", server->hostname); @@ -4433,11 +4447,18 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru kfree(tree); cifs_put_tcp_super(sb); + if (rc) { + spin_lock(&cifs_tcp_ses_lock); + tcon->tidStatus = CifsNeedTcon; + spin_unlock(&cifs_tcp_ses_lock); + } + return rc; } #else int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const struct nls_table *nlsc) { + int rc; const struct smb_version_operations *ops = tcon->ses->server->ops; /* only send once per connect */ @@ -4451,6 +4472,13 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon, const stru tcon->tidStatus = CifsInTcon; spin_unlock(&cifs_tcp_ses_lock); - return ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); + rc = ops->tree_connect(xid, tcon->ses, tcon->treeName, tcon, nlsc); + if (rc) { + spin_lock(&cifs_tcp_ses_lock); + tcon->tidStatus = CifsNeedTcon; + spin_unlock(&cifs_tcp_ses_lock); + } + + return rc; } #endif