Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp889105ybe; Fri, 13 Sep 2019 07:53:05 -0700 (PDT) X-Google-Smtp-Source: APXvYqxXdq4R7FH1ZgiGHt/VfLpvH99zrcHXUPrF+/pYTquduJ7hRIst0ySIspft2er8YubsZRi5 X-Received: by 2002:a17:906:770d:: with SMTP id q13mr13535391ejm.260.1568386385096; Fri, 13 Sep 2019 07:53:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568386385; cv=none; d=google.com; s=arc-20160816; b=Ebzf3wqjtmOECmrXlXtWrJghBg/HWwoi2zKTweAAtbbP58U7RVHQwOhY6rWDdZ7r9k exg477tVRrq9Ghn900YHL8e27w99fv0xwdq9xu7Qaa0wftw/t9wxJlDYEiPpjHiCAZC4 mEs3e93qDO8i1G0Qy30uH33uvTBG73cVcQIR81uvA8TdkBDiDqmN6sYhL0stiZ/FTV03 awOi/ihmM5Lk67Mdq3GB2qzkvOsjIMX5R7UJZvG5jfAH6p15A3RU9qx7LzXRvJlrb/5C PvtPY+VbLNY62widandVrkNUacsGePOmzOrMlhfV2JiUDOQzx0NdiLNulRRK35OsGlqh hBYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Ipo1fx2UawKeo+vtiWNS830m1MGOE/wB9gDvHPQmMEM=; b=UwMqJP1isB/i9Az2vaAC8iTyg+syMCnN8kcq/AYTRphebJ8yINRN3f2ReI2yP2Z/Pv J0df/rMhvtQOegGGKA2RPehCpwN5/Z+q1JZx0ioUknxWFrnS2bNv0GHg5txu3AvwvSXm xJTFJBUE52QwwuI/RcHaCOOsliDvg73vB5/FvQWkTS4+Jc/YR7sLDV31nWdFdyf6EByP r0Kln/6ruhUpXfdZYn8ngq0k5vWsO+Pe9epns8QFhPoq3XylujGGoHXp9jadpDwjDCXd xG+IAlkDCQ4rsZTzxJKB6yVDJQEY+rav2R4rD3YXxMo2Q6OgaOekzRl2n4hD7Zr+Cq4E +LDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=QvrLUhoA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g8si18272516edb.335.2019.09.13.07.52.41; Fri, 13 Sep 2019 07:53:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=QvrLUhoA; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390426AbfIMNTl (ORCPT + 99 others); Fri, 13 Sep 2019 09:19:41 -0400 Received: from mail.kernel.org ([198.145.29.99]:47912 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390422AbfIMNTj (ORCPT ); Fri, 13 Sep 2019 09:19:39 -0400 Received: from localhost (unknown [104.132.45.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C1B5B20640; Fri, 13 Sep 2019 13:19:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1568380778; bh=nbvMh1RIRXXzZ6TclUPYbZSby/FBqYy/SvJruTPaJuk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QvrLUhoADIz19eq0r0qA1oDEFkJaWLWK4D3jtdIGf9KOwHv4JUVnFJJdqPz/XPlJc sChdAtZlQD4A0GidJFWh2T0t1gGBhA62bmEKpETLhZsHyZImsycf7v5JphGZAaCJ0+ mxFV8X1Ij4Jfe1R5UbZea2C1Afo+H4LeKkR/jDWY= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Trond Myklebust , Sasha Levin Subject: [PATCH 4.19 176/190] NFSv4: Fix delegation state recovery Date: Fri, 13 Sep 2019 14:07:11 +0100 Message-Id: <20190913130613.814058908@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190913130559.669563815@linuxfoundation.org> References: <20190913130559.669563815@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ Upstream commit 5eb8d18ca0e001c6055da2b7f30d8f6dca23a44f ] Once we clear the NFS_DELEGATED_STATE flag, we're telling nfs_delegation_claim_opens() that we're done recovering all open state for that stateid, so we really need to ensure that we test for all open modes that are currently cached and recover them before exiting nfs4_open_delegation_recall(). Fixes: 24311f884189d ("NFSv4: Recovery of recalled read delegations...") Signed-off-by: Trond Myklebust Cc: stable@vger.kernel.org # v4.3+ Signed-off-by: Sasha Levin --- fs/nfs/delegation.c | 2 +- fs/nfs/delegation.h | 2 +- fs/nfs/nfs4proc.c | 25 ++++++++++++------------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 75fe92eaa6818..1624618c2bc72 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -153,7 +153,7 @@ again: /* Block nfs4_proc_unlck */ mutex_lock(&sp->so_delegreturn_mutex); seq = raw_seqcount_begin(&sp->so_reclaim_seqcount); - err = nfs4_open_delegation_recall(ctx, state, stateid, type); + err = nfs4_open_delegation_recall(ctx, state, stateid); if (!err) err = nfs_delegation_claim_locks(ctx, state, stateid); if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq)) diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index bb1ef8c37af42..c95477823fa6b 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h @@ -61,7 +61,7 @@ void nfs_reap_expired_delegations(struct nfs_client *clp); /* NFSv4 delegation-related procedures */ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync); -int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid, fmode_t type); +int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid); int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid); bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, struct rpc_cred **cred); bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 31ae3bd5d9d20..621e3cf90f4eb 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2113,12 +2113,10 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct case -NFS4ERR_BAD_HIGH_SLOT: case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: case -NFS4ERR_DEADSESSION: - set_bit(NFS_DELEGATED_STATE, &state->flags); nfs4_schedule_session_recovery(server->nfs_client->cl_session, err); return -EAGAIN; case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_STATEID: - set_bit(NFS_DELEGATED_STATE, &state->flags); /* Don't recall a delegation if it was lost */ nfs4_schedule_lease_recovery(server->nfs_client); return -EAGAIN; @@ -2139,7 +2137,6 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct return -EAGAIN; case -NFS4ERR_DELAY: case -NFS4ERR_GRACE: - set_bit(NFS_DELEGATED_STATE, &state->flags); ssleep(1); return -EAGAIN; case -ENOMEM: @@ -2155,8 +2152,7 @@ static int nfs4_handle_delegation_recall_error(struct nfs_server *server, struct } int nfs4_open_delegation_recall(struct nfs_open_context *ctx, - struct nfs4_state *state, const nfs4_stateid *stateid, - fmode_t type) + struct nfs4_state *state, const nfs4_stateid *stateid) { struct nfs_server *server = NFS_SERVER(state->inode); struct nfs4_opendata *opendata; @@ -2167,20 +2163,23 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, if (IS_ERR(opendata)) return PTR_ERR(opendata); nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid); - nfs_state_clear_delegation(state); - switch (type & (FMODE_READ|FMODE_WRITE)) { - case FMODE_READ|FMODE_WRITE: - case FMODE_WRITE: + if (!test_bit(NFS_O_RDWR_STATE, &state->flags)) { err = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE); if (err) - break; + goto out; + } + if (!test_bit(NFS_O_WRONLY_STATE, &state->flags)) { err = nfs4_open_recover_helper(opendata, FMODE_WRITE); if (err) - break; - /* Fall through */ - case FMODE_READ: + goto out; + } + if (!test_bit(NFS_O_RDONLY_STATE, &state->flags)) { err = nfs4_open_recover_helper(opendata, FMODE_READ); + if (err) + goto out; } + nfs_state_clear_delegation(state); +out: nfs4_opendata_put(opendata); return nfs4_handle_delegation_recall_error(server, state, stateid, NULL, err); } -- 2.20.1