From patchwork Wed Jan 23 21:10:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 10777909 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 123BA91E for ; Wed, 23 Jan 2019 21:11:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 035352D7AB for ; Wed, 23 Jan 2019 21:11:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC75F2D7B1; Wed, 23 Jan 2019 21:11:13 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI 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 27CB52D840 for ; Wed, 23 Jan 2019 21:11:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726991AbfAWVLL (ORCPT ); Wed, 23 Jan 2019 16:11:11 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:35033 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726345AbfAWVLL (ORCPT ); Wed, 23 Jan 2019 16:11:11 -0500 Received: by mail-pf1-f194.google.com with SMTP id z9so1811100pfi.2 for ; Wed, 23 Jan 2019 13:11:10 -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=PDx0iyWL61oeuUnTWzWNC22mPhRa7M1Su/1+XGqZfbE=; b=SRgvgVT42bh/ph8bhWvSbcxa9bnd4JhcccCuKJcxzlA0UAncM3f//y51C+o30MW+as Sp61z8ztsCh3Z2Z6zcuqadIyIb2JdjrVssSSFt3/HyvO+SWK3Ru6ojFvmM5V1EJY2wIs tG3kemkBtL4t9/qK33yCkt3kOqInoouO6m+noPNsZyhF0TwYfCPTNg90zXBwzVo4ATzI EDGrTPga7Uw/vtzGvh/I7o/R+KSSNINcHQsStrzAMHac7utttIuwZ3PcE7m9FD7ggk00 4zUoSLm9gOt26OmPhf4aiJfN+Jrj1ED9/vKRCn8uSo3WscvexDLywgAeRiDuynjY1JXs UkIw== 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=PDx0iyWL61oeuUnTWzWNC22mPhRa7M1Su/1+XGqZfbE=; b=QsiOksMmwBGjhJrM0i57GlvmyL0olWTo36dnRrSt/xr2fPsu/iEDKI2dd/8KweAUyO lWDzriURHG7n/r9XKSLFw9V7Z78c7XgwGpZAoMIumQaJNuk87gDvuelPV8yJ0IUhvY7a +KWiXDAvRi0TFCVCIACMDgRY5PuOhly2Mhq4+yaGvJRiix3dhdjWnE+qSjFT48gzpHcM u7AjZ3v1JSQz+y4AYFXd7szNI3ZQ8PdOA1TFcqkhy90IO317S62zLu2xH9MTnqjXTMsm qzT31+g05qaOSNW1+U/z16GciSR/4VPiesuIHRxga7q/EUnWvvaYhezs+mf+WI3pg4WH esWQ== X-Gm-Message-State: AJcUukdiatJA8Sz7UyImJVaWIj9+uuFFeRlXPV6CdLO9rRpUPVBvMYFN LqmTYMTnK6Ra0Fdpeu0b/uzHf0w= X-Google-Smtp-Source: ALg8bN5z0nR/e+j18aOdc8a3Ub5m4yJPyOrtV/E8Ym44shCw7yBq5Da2hAmsL6URL+EfPEo0961pFA== X-Received: by 2002:a63:de46:: with SMTP id y6mr3481538pgi.198.1548277870100; Wed, 23 Jan 2019 13:11:10 -0800 (PST) Received: from ubuntu-vm.corp.microsoft.com ([2001:4898:80e8:f:a17f:4e9f:6b7c:507d]) by smtp.gmail.com with ESMTPSA id n73sm28063714pfj.148.2019.01.23.13.11.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Jan 2019 13:11:09 -0800 (PST) From: Pavel Shilovsky X-Google-Original-From: Pavel Shilovsky To: linux-cifs@vger.kernel.org, Steve French , Ronnie Sahlberg Subject: [PATCH 14/15] CIFS: Check for reconnects before sending async requests Date: Wed, 23 Jan 2019 13:10:44 -0800 Message-Id: <1548277845-6746-15-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1548277845-6746-1-git-send-email-pshilov@microsoft.com> References: <1548277845-6746-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 X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 5b54882..8f44415 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -851,7 +851,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); @@ -1803,7 +1803,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); @@ -2334,7 +2334,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 2a2ebaa..8d3a96d 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -2994,7 +2994,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); @@ -3294,7 +3294,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); @@ -3587,7 +3588,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);