From patchwork Tue Sep 20 16:55:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 9342105 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 0A276607D0 for ; Tue, 20 Sep 2016 16:56:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFF3129495 for ; Tue, 20 Sep 2016 16:56:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E47D12996E; Tue, 20 Sep 2016 16:56:19 +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 6341029495 for ; Tue, 20 Sep 2016 16:56:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755281AbcITQ4S (ORCPT ); Tue, 20 Sep 2016 12:56:18 -0400 Received: from mail-qt0-f195.google.com ([209.85.216.195]:33882 "EHLO mail-qt0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754132AbcITQ4R (ORCPT ); Tue, 20 Sep 2016 12:56:17 -0400 Received: by mail-qt0-f195.google.com with SMTP id e5so719984qtb.1 for ; Tue, 20 Sep 2016 09:56:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=ls59J8nYHdC4oh4imP0VXv4k56cOjzZz8dpC2U5sHZo=; b=xNmYpiMtIb8Pl4OexEwMDRVLVIIApyKOuOh8uaWtffq1P7F9ekQO4weizxr2Zqo/U7 bTo87rC8EqJBq0qcbTVYpnj1YYaAzkSyJiYRWZO+S6E09E1S2HEh/tSwAQwqZEkXF4f7 lVZLmo4fEaB6qseGsSHkg1N3tOPuhbiELjDfJgYzsgz6q9SE7h9pClVCqJkjTuoNrolI bfFkvwKC72p4b/+JGVI/AjNXQaiGhsSQQosQ/xntKdFzm546BO8Ccw+VplsSf1rU7ooe Cj9YQZU4OHxz6lD04Q1RmfT2vOT5fyz56tL+qnCyVxrhiTIemigKOqhXCsie+3COV8ub 4Cwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=ls59J8nYHdC4oh4imP0VXv4k56cOjzZz8dpC2U5sHZo=; b=Ckq2E7EvgfodtkY1cPn2gOp/PZrbBFi33pKh9mbcwiR+HRWNNWKxME5BkYwkANlXBi w8skmy1aNKh94789HCeXbdFdDQDGwWyifHWZAl3/HKpVppWgEvAHvl9jeRb2LSlpyBG+ nds4G8jp8Jma0r+P12Er+2WfhoB1gScBn0etoaznRxnynr63xYbrr5Hu8KWsidN0k8/7 pHN7n8Mp+DXr7swLMy+66Tptq6gYgYorT1miOHIJlbzSOGiQ4ZWSnLW227OC+MgMdJQS 55Gcqjs1wKg913J3IsCTR9qkEhykReUK4lFOSYUcX4cAS9Y9KmO4kj4gbqZSUTeBOoQU ZpLw== X-Gm-Message-State: AE9vXwOMo7rQiLkRI/NdDzoukyc0ZTzN2KjbcERK/sHAfLF3Lesa8/XnbrUtnDRjD+KdVQ== X-Received: by 10.237.52.2 with SMTP id w2mr22578170qtd.112.1474390576213; Tue, 20 Sep 2016 09:56:16 -0700 (PDT) Received: from leira.trondhjem.org.localdomain (50-108-86-94.adr01.mskg.mi.frontiernet.net. [50.108.86.94]) by smtp.gmail.com with ESMTPSA id i4sm16537202qte.40.2016.09.20.09.56.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Sep 2016 09:56:15 -0700 (PDT) From: Trond Myklebust To: anna.schumaker@netapp.com Cc: linux-nfs@vger.kernel.org, Oleg Drokin Subject: [PATCH v6 01/29] NFSv4.1: Don't deadlock the state manager on the SEQUENCE status flags Date: Tue, 20 Sep 2016 12:55:43 -0400 Message-Id: <1474390571-17106-2-git-send-email-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1474390571-17106-1-git-send-email-trond.myklebust@primarydata.com> References: <1474390571-17106-1-git-send-email-trond.myklebust@primarydata.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP As described in RFC5661, section 18.46, some of the status flags exist in order to tell the client when it needs to acknowledge the existence of revoked state on the server and/or to recover state. Those flags will then remain set until the recovery procedure is done. In order to avoid looping, the client therefore needs to ignore those particular flags while recovering. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4proc.c | 5 ++++- fs/nfs/nfs4session.h | 1 + fs/nfs/nfs4state.c | 12 +++++++++++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index f230aa62ca59..4390d73a92e5 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -439,7 +439,7 @@ extern void nfs4_schedule_path_down_recovery(struct nfs_client *clp); extern int nfs4_schedule_stateid_recovery(const struct nfs_server *, struct nfs4_state *); extern int nfs4_schedule_migration_recovery(const struct nfs_server *); extern void nfs4_schedule_lease_moved_recovery(struct nfs_client *); -extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); +extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags, bool); extern void nfs41_handle_server_scope(struct nfs_client *, struct nfs41_server_scope **); extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 251e48e7ba16..6b700c59eede 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -616,6 +616,7 @@ int nfs40_setup_sequence(struct nfs4_slot_table *tbl, } spin_unlock(&tbl->slot_tbl_lock); + slot->privileged = args->sa_privileged ? 1 : 0; args->sa_slot = slot; res->sr_slot = slot; @@ -728,7 +729,8 @@ static int nfs41_sequence_process(struct rpc_task *task, clp = session->clp; do_renew_lease(clp, res->sr_timestamp); /* Check sequence flags */ - nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags); + nfs41_handle_sequence_flag_errors(clp, res->sr_status_flags, + !!slot->privileged); nfs41_update_target_slotid(slot->table, slot, res); break; case 1: @@ -875,6 +877,7 @@ int nfs41_setup_sequence(struct nfs4_session *session, } spin_unlock(&tbl->slot_tbl_lock); + slot->privileged = args->sa_privileged ? 1 : 0; args->sa_slot = slot; dprintk("<-- %s slotid=%u seqid=%u\n", __func__, diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h index 3bb6af70973c..dae385500005 100644 --- a/fs/nfs/nfs4session.h +++ b/fs/nfs/nfs4session.h @@ -23,6 +23,7 @@ struct nfs4_slot { u32 slot_nr; u32 seq_nr; unsigned int interrupted : 1, + privileged : 1, seq_done : 1; }; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index cada00aa5096..9801b5bb5fac 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -2227,13 +2227,22 @@ static void nfs41_handle_cb_path_down(struct nfs_client *clp) nfs4_schedule_state_manager(clp); } -void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) +void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags, + bool recovery) { if (!flags) return; dprintk("%s: \"%s\" (client ID %llx) flags=0x%08x\n", __func__, clp->cl_hostname, clp->cl_clientid, flags); + /* + * If we're called from the state manager thread, then assume we're + * already handling the RECLAIM_NEEDED and/or STATE_REVOKED. + * Those flags are expected to remain set until we're done + * recovering (see RFC5661, section 18.46.3). + */ + if (recovery) + goto out_recovery; if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) nfs41_handle_server_reboot(clp); @@ -2246,6 +2255,7 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) nfs4_schedule_lease_moved_recovery(clp); if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED) nfs41_handle_recallable_state_revoked(clp); +out_recovery: if (flags & SEQ4_STATUS_BACKCHANNEL_FAULT) nfs41_handle_backchannel_fault(clp); else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |