From patchwork Wed Aug 31 02:11:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 9306243 X-Patchwork-Delegate: Trond.Myklebust@netapp.com 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 84CF5607F0 for ; Wed, 31 Aug 2016 02:12:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 73A7D28DE7 for ; Wed, 31 Aug 2016 02:12:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 687E528E08; Wed, 31 Aug 2016 02:12:18 +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 E735928DE7 for ; Wed, 31 Aug 2016 02:12:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758225AbcHaCMQ (ORCPT ); Tue, 30 Aug 2016 22:12:16 -0400 Received: from mail-it0-f68.google.com ([209.85.214.68]:35611 "EHLO mail-it0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757562AbcHaCMP (ORCPT ); Tue, 30 Aug 2016 22:12:15 -0400 Received: by mail-it0-f68.google.com with SMTP id f128so4119699ith.2 for ; Tue, 30 Aug 2016 19:12:15 -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=rE6TJG0/QMSYINFlnCc6F14NaisjkuEP3QK0Wnp+hao=; b=jT81HBN4E7/9Vb4535d++jY8tyLUJnMoUvA7q/VI6rPbeul2kHvBTlUiWq3YT1Ig/v DLZ6bjEmPsGMH7GolgOmQvJte6Xselqla/3Ty00GE6Xavry29uW3JdPrJSyPpnq90nH2 WdZ4/HQrCdegOmve1YB9i1livScdXxlqRyBD4JtJgPoj/sa2Wfs6puOZWWfK31cJ9RoF LsarNl/J9SSjSF+S++3DxMAlhT1GQR5mGQjRFIz09XspGFmwvQRix9yRylQZzUZ+Jeiu 2ZszLSXoDUttJJWL72urWwo7LpPyy7yEo8oheexbEy8aPuiw0YNBdkqRJmooyl771wmO wSsg== 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=rE6TJG0/QMSYINFlnCc6F14NaisjkuEP3QK0Wnp+hao=; b=IsSbWEJJtRD1NE/3kCEeupozQ4VrbadLHSuyvePxdngTGwYdtvdPKsSI0vB/oN2HJI 5mwgA5IoyZmYQ6KopQOLPD4LVUrtEIojecpk1/BfOUEa8C2SoS9N60K3ISeSehwgj9SG EpLkX4LVyt0r3HrzSMYn7bWBsnXnxra7SWk0dj2ajGL2pEHrQk1mTBfAS9+VsiyYnqno yysG+qrzM3jfRANnYb0Jz+RFe7TWkhLSmA7hdDYxxFsnqvfkkboDuIAJiefPbp3J0L3m hsdIfQ0pZHR+7WdaMfIz2ThFHV/vykNlsOHyT91moA5pLyi3u55NOF7ob6EwxM4gMIPQ higw== X-Gm-Message-State: AE9vXwNsWXX57+4HgFvM30IbPMfJSSOkoXQ7EaUAfv6c/qIDF3kmdpqsj284NGQ7vrHibw== X-Received: by 10.107.15.89 with SMTP id x86mr2756168ioi.21.1472609534773; Tue, 30 Aug 2016 19:12:14 -0700 (PDT) Received: from leira.trondhjem.org.localdomain (c-68-49-162-121.hsd1.mi.comcast.net. [68.49.162.121]) by smtp.gmail.com with ESMTPSA id x77sm895268ioi.3.2016.08.30.19.12.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Aug 2016 19:12:14 -0700 (PDT) From: Trond Myklebust To: anna.schumaker@netapp.com Cc: linux-nfs@vger.kernel.org Subject: [PATCH 3/7] NFSv4.1: Add a helper function to deal with expired stateids Date: Tue, 30 Aug 2016 22:11:40 -0400 Message-Id: <1472609504-69094-4-git-send-email-trond.myklebust@primarydata.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1472609504-69094-3-git-send-email-trond.myklebust@primarydata.com> References: <1472609504-69094-1-git-send-email-trond.myklebust@primarydata.com> <1472609504-69094-2-git-send-email-trond.myklebust@primarydata.com> <1472609504-69094-3-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 In NFSv4.1 and newer, if the server decides to revoke some or all of the protocol state, the client is required to iterate through all the stateids that it holds and call TEST_STATEID to determine which stateids still correspond to valid state, and then call FREE_STATEID on the others. Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 2d2c1a46c3b9..13640bb3dcfb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2405,6 +2405,26 @@ static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st } #if defined(CONFIG_NFS_V4_1) +static int nfs41_test_and_free_expired_stateid(struct nfs_server *server, + nfs4_stateid *stateid, + struct rpc_cred *cred) +{ + int status; + + status = nfs41_test_stateid(server, stateid, cred); + + switch (status) { + case -NFS4ERR_EXPIRED: + case -NFS4ERR_ADMIN_REVOKED: + case -NFS4ERR_DELEG_REVOKED: + /* Ack the revoked state to the server */ + nfs41_free_stateid(server, stateid, cred); + case -NFS4ERR_BAD_STATEID: + return status; + } + return NFS_OK; +} + static void nfs41_check_delegation_stateid(struct nfs4_state *state) { struct nfs_server *server = NFS_SERVER(state->inode); @@ -2429,16 +2449,10 @@ static void nfs41_check_delegation_stateid(struct nfs4_state *state) nfs4_stateid_copy(&stateid, &delegation->stateid); cred = get_rpccred(delegation->cred); rcu_read_unlock(); - status = nfs41_test_stateid(server, &stateid, cred); + status = nfs41_test_and_free_expired_stateid(server, &stateid, cred); trace_nfs4_test_delegation_stateid(state, NULL, status); - - if (status != NFS_OK) { - /* Free the stateid unless the server explicitly - * informs us the stateid is unrecognized. */ - if (status != -NFS4ERR_BAD_STATEID) - nfs41_free_stateid(server, &stateid, cred); + if (status != NFS_OK) nfs_finish_clear_delegation_stateid(state); - } put_rpccred(cred); } @@ -2464,14 +2478,9 @@ static int nfs41_check_open_stateid(struct nfs4_state *state) (test_bit(NFS_O_RDWR_STATE, &state->flags) == 0)) return -NFS4ERR_BAD_STATEID; - status = nfs41_test_stateid(server, stateid, cred); + status = nfs41_test_and_free_expired_stateid(server, stateid, cred); trace_nfs4_test_open_stateid(state, NULL, status); if (status != NFS_OK) { - /* Free the stateid unless the server explicitly - * informs us the stateid is unrecognized. */ - if (status != -NFS4ERR_BAD_STATEID) - nfs41_free_stateid(server, stateid, cred); - clear_bit(NFS_O_RDONLY_STATE, &state->flags); clear_bit(NFS_O_WRONLY_STATE, &state->flags); clear_bit(NFS_O_RDWR_STATE, &state->flags); @@ -6106,17 +6115,11 @@ static int nfs41_check_expired_locks(struct nfs4_state *state) if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) { struct rpc_cred *cred = lsp->ls_state->owner->so_cred; - status = nfs41_test_stateid(server, + status = nfs41_test_and_free_expired_stateid(server, &lsp->ls_stateid, cred); trace_nfs4_test_lock_stateid(state, lsp, status); if (status != NFS_OK) { - /* Free the stateid unless the server - * informs us the stateid is unrecognized. */ - if (status != -NFS4ERR_BAD_STATEID) - nfs41_free_stateid(server, - &lsp->ls_stateid, - cred); clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags); ret = status; }