From patchwork Mon Oct 26 14:34:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Henrique Cerri X-Patchwork-Id: 1387804 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CKcn147rvz9sTD; Tue, 27 Oct 2020 01:35:01 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1kX3aL-0004xz-Ey; Mon, 26 Oct 2020 14:34:57 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kX3aG-0004x8-NJ for kernel-team@lists.ubuntu.com; Mon, 26 Oct 2020 14:34:52 +0000 Received: from mail-qt1-f197.google.com ([209.85.160.197]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1kX3aG-0001ir-DC for kernel-team@lists.ubuntu.com; Mon, 26 Oct 2020 14:34:52 +0000 Received: by mail-qt1-f197.google.com with SMTP id r4so6283853qta.9 for ; Mon, 26 Oct 2020 07:34:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+cI3AtpJ2InEEDlR+2DNHpi0cRcx+4e0fQhooLmD2cs=; b=guX7TsgWqwZZ3G/8nu5uqluEVpvfYSxaSBHZfTtQvS4dNEPxrSin+gaNN6eG2LyNDG 7QdGKXqCDVQaI8jNMDOcdTgTlH/4DKvT+bdgBDL2kvBQBOxdQuhOTTXBvUP0VUce7kgD YkYGL+BxzpLR2spM1WQmfU6IFUhQ2PI8rSL+ziwOTJhdWzhmDZ5vV0EmrMWce3aosYrX OEaqBZX+IKCTtoCK/PpSV+qdr6gH/tlhRu0Jd2aNwikNQ3NCN/z9oBCfhB6HONoOa/M6 iSNKvph/3fnkqrP/qIV+TXvFJKh8eO9dPB+3mT4mkM1YeO/AhWH2gKp8VkEQOjskK65m AsUw== X-Gm-Message-State: AOAM532vWd5rCHM7XJfgWKfoOxUSuhKtc31Gq2aJpmWVHu6nSKV34hWf 2mzLE5bbs0Dn8QCo7TINsrHm7gBYcVChzwuGwcL4ap2wg/k9cyBeqg/PDKKhLURUToip4/eHivz f8DnHusjk6vdtBYmpCZhFYVjEqCl945euQqTtEgcp X-Received: by 2002:a05:620a:842:: with SMTP id u2mr15956116qku.214.1603722891139; Mon, 26 Oct 2020 07:34:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxGCxUSfSrImW/2JCVzyxF6pds+EYsEL6MLIQsPbIm8dTTwrqdM8/rjcvhz1nz1t4IMcPcJ+Q== X-Received: by 2002:a05:620a:842:: with SMTP id u2mr15956094qku.214.1603722890807; Mon, 26 Oct 2020 07:34:50 -0700 (PDT) Received: from valinor.lan (200-232-230-238.dsl.telesp.net.br. [200.232.230.238]) by smtp.gmail.com with ESMTPSA id y125sm6386480qkb.114.2020.10.26.07.34.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Oct 2020 07:34:50 -0700 (PDT) From: Marcelo Henrique Cerri To: kernel-team@lists.ubuntu.com Subject: [bionic:linux-azure-4.15][PATCH 2/2] cifs: Fix potential softlockups while refreshing DFS cache Date: Mon, 26 Oct 2020 11:34:43 -0300 Message-Id: <20201026143443.2526723-3-marcelo.cerri@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201026143443.2526723-1-marcelo.cerri@canonical.com> References: <20201026143443.2526723-1-marcelo.cerri@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Paulo Alcantara (SUSE) BugLink: https://bugs.launchpad.net/bugs/1882268 We used to skip reconnects on all SMB2_IOCTL commands due to SMB3+ FSCTL_VALIDATE_NEGOTIATE_INFO - which made sense since we're still establishing a SMB session. However, when refresh_cache_worker() calls smb2_get_dfs_refer() and we're under reconnect, SMB2_ioctl() will not be able to get a proper status error (e.g. -EHOSTDOWN in case we failed to reconnect) but an -EAGAIN from cifs_send_recv() thus looping forever in refresh_cache_worker(). Fixes: e99c63e4d86d ("SMB3: Fix deadlock in validate negotiate hits reconnect") Signed-off-by: Paulo Alcantara (SUSE) Suggested-by: Aurelien Aptel Reviewed-by: Aurelien Aptel Signed-off-by: Steve French (backported from commit 84a1f5b1cc6fd7f6cd99fc5630c36f631b19fa60) [marcelo.cerri: Adapted the changes from smb2_plain_req_init() to small_smb2_init() to avoid picking too many unrelated changes] Signed-off-by: Marcelo Henrique Cerri --- fs/cifs/smb2pdu.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index ec2f7c377a2b..ab1df4311a6d 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -166,7 +166,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) if (tcon == NULL) return 0; - if (smb2_command == SMB2_TREE_CONNECT || smb2_command == SMB2_IOCTL) + if (smb2_command == SMB2_TREE_CONNECT) return 0; if (tcon->tidStatus == CifsExiting) { @@ -372,18 +372,13 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon, * function must have filled in request_buf pointer. The returned buffer * has RFC1001 length at the beginning. */ -static int -small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, - void **request_buf) +static int __small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, + void **request_buf) { - int rc; + int rc = 0; unsigned int total_len; struct smb2_pdu *pdu; - rc = smb2_reconnect(smb2_command, tcon); - if (rc) - return rc; - /* BB eventually switch this to SMB2 specific small buf size */ *request_buf = cifs_small_buf_get(); if (*request_buf == NULL) { @@ -409,6 +404,29 @@ small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, return rc; } +static int small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, + void **request_buf) +{ + int rc; + + rc = smb2_reconnect(smb2_command, tcon); + if (rc) + return rc; + + return __small_smb2_init(smb2_command, tcon, request_buf); +} + +static int small_smb2_ioctl_init(u32 opcode, struct cifs_tcon *tcon, + void **request_buf) +{ + /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */ + if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) { + return __small_smb2_init(SMB2_IOCTL, tcon, request_buf); + } + return small_smb2_init(SMB2_IOCTL, tcon, request_buf); +} + + #ifdef CONFIG_CIFS_SMB311 /* offset is sizeof smb2_negotiate_req - 4 but rounded up to 8 bytes */ #define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) - 4 */ @@ -1937,7 +1955,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (!ses || !(ses->server)) return -EIO; - rc = small_smb2_init(SMB2_IOCTL, tcon, (void **) &req); + rc = small_smb2_ioctl_init(opcode, tcon, (void **) &req); if (rc) return rc;