From patchwork Fri Feb 1 20:04:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 1035136 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="o8zKh3i/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43rp3c5CP7z9s6w for ; Sat, 2 Feb 2019 07:04:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730755AbfBAUEo (ORCPT ); Fri, 1 Feb 2019 15:04:44 -0500 Received: from mail-pl1-f178.google.com ([209.85.214.178]:33821 "EHLO mail-pl1-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730775AbfBAUEn (ORCPT ); Fri, 1 Feb 2019 15:04:43 -0500 Received: by mail-pl1-f178.google.com with SMTP id w4so3755494plz.1 for ; Fri, 01 Feb 2019 12:04:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=01Szu3F6S9vDeVaJ2wBf3+c1URmIwthqWF4PdGjqCGY=; b=o8zKh3i/lA6gwQEIO43ukBp2TaxGNB34vPLa5Uic3kSmRxtGIZo6UF/hJvEqTlQdrE ChxnEluT5pH51caULq2nhtHCP+UoCjcPhewKqZcaZMhLakE06SSytdawA+HkwcPQ0QMj 1udoAv5XNPP7Ck0Fy8EvRBYzDYVKc7qgsiZhPuwFhJf5UJpq5qL0ImazioCdvpwFeQrC 4GspfJhe0e6hBVuKFrGbI1QFeGWf2kKamMYBuEP6n2qcT8gFAY+drSbik9hFdAnv+b3H hKoIKGTM1tmtDd6D3vrivQtQxUjozC3aDHc9ST4Voga1VXisgevdRUpeYlC9nJTN0ku4 OI1g== 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; bh=01Szu3F6S9vDeVaJ2wBf3+c1URmIwthqWF4PdGjqCGY=; b=IxDialIrAvEreJL/eT/aC1np/EnJvGV48BhUbM3Q9wa3/4MgZcgb/2+291JvOKOJar K7Y2KU/F5lVVC35G23DErD5JssrnDoylrsqG26HBtQ6CIhxXfHlDt7ETUB1lgLT1Ewz9 Kr2qXTS8Kxq2qj+WCutugujzGK50BTV366hagIBH4MtlNBlSLxPToNf26xSRGixGnlcT oZ+7keEpcRDDpWw6B82XYwUyMGDa5CJ5y0RPNsQJpbrME7x2mk/5sRq549Eo3ndbdu7h aaUclN7K0CdQ/eOgtZzU7gCWvMFFapZhmuQVgTBDEaU8wYoh67BVZE8eYVuPzuBWBxV4 g0vw== X-Gm-Message-State: AJcUukdX0XtF1ouVEM82NmXFlJxoyssChhdsma6711Y6PpCFnbpV3OxZ LDvsxo3AeLHNbRMwHL623TNqfAU= X-Google-Smtp-Source: ALg8bN4Z1e1qLkrl5Py2vTRcxEPIgQbtY31w2dehSNib+2Z/fiJ1Sv+sjngSb5VEAhyWY6GbNFZsZw== X-Received: by 2002:a17:902:9a04:: with SMTP id v4mr41590502plp.34.1549051482087; Fri, 01 Feb 2019 12:04:42 -0800 (PST) Received: from ubuntu-vm.corp.microsoft.com ([2001:4898:80e8:0:a18e:4e9f:6b7c:507d]) by smtp.gmail.com with ESMTPSA id x11sm24247451pfe.72.2019.02.01.12.04.40 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 01 Feb 2019 12:04:40 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH 14/23] CIFS: Check for reconnects before sending async requests Date: Fri, 1 Feb 2019 12:04:03 -0800 Message-Id: <1549051452-5968-16-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1549051452-5968-1-git-send-email-pshilov@microsoft.com> References: <1549051452-5968-1-git-send-email-pshilov@microsoft.com> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org The reconnect might have happended after we obtained credits and before we acquired srv_mutex. Check for that under the mutex and retry an async operation if the reconnect is detected. Signed-off-by: Pavel Shilovsky Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 3 ++- fs/cifs/cifssmb.c | 6 +++--- fs/cifs/smb2pdu.c | 7 ++++--- fs/cifs/transport.c | 18 ++++++++++++++++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 7a9a9fd..9e8394f 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -93,7 +93,8 @@ extern int cifs_discard_remaining_data(struct TCP_Server_Info *server); extern int cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, mid_receive_t *receive, mid_callback_t *callback, - mid_handle_t *handle, void *cbdata, const int flags); + mid_handle_t *handle, void *cbdata, const int flags, + const struct cifs_credits *exist_credits); extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, struct smb_rqst *rqst, int *resp_buf_type, const int flags, struct kvec *resp_iov); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index cf97fc0..6c89279 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -860,7 +860,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server) iov[1].iov_base = (char *)smb + 4; rc = cifs_call_async(server, &rqst, NULL, cifs_echo_callback, NULL, - server, CIFS_ASYNC_OP | CIFS_ECHO_OP); + server, CIFS_ASYNC_OP | CIFS_ECHO_OP, NULL); if (rc) cifs_dbg(FYI, "Echo request failed: %d\n", rc); @@ -1812,7 +1812,7 @@ cifs_async_readv(struct cifs_readdata *rdata) kref_get(&rdata->refcount); rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive, - cifs_readv_callback, NULL, rdata, 0); + cifs_readv_callback, NULL, rdata, 0, NULL); if (rc == 0) cifs_stats_inc(&tcon->stats.cifs_stats.num_reads); @@ -2352,7 +2352,7 @@ cifs_async_writev(struct cifs_writedata *wdata, kref_get(&wdata->refcount); rc = cifs_call_async(tcon->ses->server, &rqst, NULL, - cifs_writev_callback, NULL, wdata, 0); + cifs_writev_callback, NULL, wdata, 0, NULL); if (rc == 0) cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 746be24..8f92c22 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3025,7 +3025,7 @@ SMB2_echo(struct TCP_Server_Info *server) iov[0].iov_base = (char *)req; rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL, - server, CIFS_ECHO_OP); + server, CIFS_ECHO_OP, NULL); if (rc) cifs_dbg(FYI, "Echo request failed: %d\n", rc); @@ -3334,7 +3334,8 @@ smb2_async_readv(struct cifs_readdata *rdata) kref_get(&rdata->refcount); rc = cifs_call_async(io_parms.tcon->ses->server, &rqst, cifs_readv_receive, smb2_readv_callback, - smb3_handle_read_data, rdata, flags); + smb3_handle_read_data, rdata, flags, + &rdata->credits); if (rc) { kref_put(&rdata->refcount, cifs_readdata_release); cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE); @@ -3636,7 +3637,7 @@ smb2_async_writev(struct cifs_writedata *wdata, kref_get(&wdata->refcount); rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL, - wdata, flags); + wdata, flags, &wdata->credits); if (rc) { trace_smb3_write_err(0 /* no xid */, req->PersistentFileId, diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 8b512a9..26e9912 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -634,7 +634,8 @@ cifs_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) int cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, mid_receive_t *receive, mid_callback_t *callback, - mid_handle_t *handle, void *cbdata, const int flags) + mid_handle_t *handle, void *cbdata, const int flags, + const struct cifs_credits *exist_credits) { int rc, timeout, optype; struct mid_q_entry *mid; @@ -650,9 +651,22 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, return rc; credits.value = 1; credits.instance = instance; - } + } else + instance = exist_credits->instance; mutex_lock(&server->srv_mutex); + + /* + * We can't use credits obtained from the previous session to send this + * request. Check if there were reconnects after we obtained credits and + * return -EAGAIN in such cases to let callers handle it. + */ + if (instance != server->reconnect_instance) { + mutex_unlock(&server->srv_mutex); + add_credits_and_wake_if(server, &credits, optype); + return -EAGAIN; + } + mid = server->ops->setup_async_request(server, rqst); if (IS_ERR(mid)) { mutex_unlock(&server->srv_mutex);