From patchwork Mon Jul 9 15:44:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 1173901 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 5B6C840B21 for ; Mon, 9 Jul 2012 15:46:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751928Ab2GIPoG (ORCPT ); Mon, 9 Jul 2012 11:44:06 -0400 Received: from mail-yx0-f174.google.com ([209.85.213.174]:55958 "EHLO mail-yx0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751694Ab2GIPoE (ORCPT ); Mon, 9 Jul 2012 11:44:04 -0400 Received: by yenl2 with SMTP id l2so10189699yen.19 for ; Mon, 09 Jul 2012 08:44:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:subject:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-type:content-transfer-encoding; bh=qdkSjxo5vTqBqNwTHx/JrwfvwDHTGaVye+mSOCx0dUI=; b=L8dtgN+h4aZ/22q3iE5gP4KGF1jY2llm+xyfo1j3yeUzfvIBHu376ueyaXVJHlWyNw zZBYqZrlNXXroVNRQDMfsI7qBSpc6l+ftVrygXgdbaBcdK6EKU53fGUTz1ws0Ol09UsN BBmWoOiTox6FT1GWeCdImXa55/jnrNcAtH9OAHU6HLsj5OZuBX2xT1OSWy6erpPfqWu9 qNL+KTiR8KbdKsRwGvZQf6k9mtgh/IgEP/Ucb6Gobkz7EXJZElWZdSMCBfLpMSiOGV6I mdpjXVYkfKd9ziiSPwuIgSJzVKu42mPtAYC1Xxyrf6Zclyc9Jo9QuQ1rX9emA67tzIlU DEvQ== Received: by 10.50.208.106 with SMTP id md10mr8914762igc.54.1341848641993; Mon, 09 Jul 2012 08:44:01 -0700 (PDT) Received: from degas.1015granger.net (adsl-99-26-161-222.dsl.sfldmi.sbcglobal.net. [99.26.161.222]) by mx.google.com with ESMTPS id bp8sm20581068igb.12.2012.07.09.08.44.01 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 09 Jul 2012 08:44:01 -0700 (PDT) From: Chuck Lever Subject: [PATCH 02/14] NFS: Properly sort TEST_STATEID results To: trond.myklebust@netapp.com Cc: linux-nfs@vger.kernel.org Date: Mon, 09 Jul 2012 11:44:00 -0400 Message-ID: <20120709154400.1604.10590.stgit@degas.1015granger.net> In-Reply-To: <20120709153355.1604.14102.stgit@degas.1015granger.net> References: <20120709153355.1604.14102.stgit@degas.1015granger.net> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org The result of a TEST_STATEID operation can indicate a few different things: o If NFS_OK is returned, then the client can continue using the state ID under test, and skip recovery. o RFC 5661 says that if and only if the state ID was revoked, then the client must perform an explicit FREE_STATEID before trying to re-open. o If the server doesn't recognize the state ID at all, then no FREE_STATEID is needed, and the client can immediately continue with open recovery. Signed-off-by: Chuck Lever --- fs/nfs/nfs4proc.c | 36 ++++++++++++++++++++++++++++++++++-- 1 files changed, 34 insertions(+), 2 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 971ec8c..60a320c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1756,6 +1756,14 @@ static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *sta } #if defined(CONFIG_NFS_V4_1) +/** + * nfs41_check_expired_stateid - does a state ID need recovery? + * + * @state: NFSv4 open state for an inode + * + * Returns NFS_OK if recovery for this state ID is now finished. + * Otherwise a negative NFS4ERR value is returned. + */ static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *stateid, unsigned int flags) { int status = NFS_OK; @@ -1763,8 +1771,16 @@ static int nfs41_check_expired_stateid(struct nfs4_state *state, nfs4_stateid *s if (state->flags & flags) { status = nfs41_test_stateid(server, stateid); - if (status != NFS_OK) { + switch (status) { + case NFS_OK: + /* server recognizes this one, don't recover */ + break; + case -NFS4ERR_ADMIN_REVOKED: + case -NFS4ERR_DELEG_REVOKED: + /* state was revoked, free then re-open */ nfs41_free_stateid(server, stateid); + default: + /* anything else: just re-open it */ state->flags &= ~flags; } } @@ -4698,6 +4714,14 @@ out: } #if defined(CONFIG_NFS_V4_1) +/** + * nfs41_check_expired_locks - clear lock state IDs + * + * @state: NFSv4 open state for a file + * + * Returns NFS_OK if recovery for this state ID is now finished. + * Otherwise a negative NFS4ERR value is returned. + */ static int nfs41_check_expired_locks(struct nfs4_state *state) { int status, ret = NFS_OK; @@ -4707,8 +4731,16 @@ static int nfs41_check_expired_locks(struct nfs4_state *state) list_for_each_entry(lsp, &state->lock_states, ls_locks) { if (lsp->ls_flags & NFS_LOCK_INITIALIZED) { status = nfs41_test_stateid(server, &lsp->ls_stateid); - if (status != NFS_OK) { + switch (status) { + case NFS_OK: + /* server recognizes this one, don't re-lock */ + break; + case -NFS4ERR_ADMIN_REVOKED: + case -NFS4ERR_DELEG_REVOKED: + /* lock was revoked, free then re-lock */ nfs41_free_stateid(server, &lsp->ls_stateid); + default: + /* anything else: just re-lock it */ lsp->ls_flags &= ~NFS_LOCK_INITIALIZED; ret = status; }