From patchwork Mon Sep 29 16:31:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Adamson X-Patchwork-Id: 4997801 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2B275BEEA6 for ; Mon, 29 Sep 2014 16:32:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 576ED20172 for ; Mon, 29 Sep 2014 16:32:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1FA1C201B9 for ; Mon, 29 Sep 2014 16:32:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754548AbaI2QcP (ORCPT ); Mon, 29 Sep 2014 12:32:15 -0400 Received: from mx11.netapp.com ([216.240.18.76]:38754 "EHLO mx11.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754342AbaI2QcO (ORCPT ); Mon, 29 Sep 2014 12:32:14 -0400 X-IronPort-AV: E=Sophos;i="5.04,620,1406617200"; d="scan'208";a="157736047" Received: from vmwexchts03-prd.hq.netapp.com ([10.122.105.31]) by mx11-out.netapp.com with ESMTP; 29 Sep 2014 09:32:03 -0700 Received: from smtp1.corp.netapp.com (10.57.156.124) by VMWEXCHTS03-PRD.hq.netapp.com (10.122.105.31) with Microsoft SMTP Server id 15.0.913.22; Mon, 29 Sep 2014 09:31:49 -0700 Received: from rhel7-snap12.androsad.fake (vpn2ntap-227528.vpn.netapp.com [10.55.69.36]) by smtp1.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id s8TGW0nJ014818; Mon, 29 Sep 2014 09:32:01 -0700 (PDT) From: To: CC: , Andy Adamson Subject: [PATCH Version 3 1/1] NFSv4.1: Fix an NFSv4.1 state renewal regression Date: Mon, 29 Sep 2014 12:31:57 -0400 Message-ID: <1412008317-36182-2-git-send-email-andros@netapp.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1412008317-36182-1-git-send-email-andros@netapp.com> References: <1412008317-36182-1-git-send-email-andros@netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Andy Adamson Commit 2f60ea6b8ced ("NFSv4: The NFSv4.0 client must send RENEW calls if it holds a delegation") set the NFS4_RENEW_TIMEOUT flag in nfs4_renew_state, and does not put an nfs41_proc_async_sequence call, the NFSv4.1 lease renewal heartbeat call, on the wire to renew the NFSv4.1 state if the flag was not set. The NFS4_RENEW_TIMEOUT flag is set when "now" is after the last renewal (cl_last_renewal) plus the lease time divided by 3. This is arbitrary and sometimes does the following: In normal operation, the only way a future state renewal call is put on the wire is via a call to nfs4_schedule_state_renewal, which schedules a nfs4_renew_state workqueue task. nfs4_renew_state determines if the NFS4_RENEW_TIMEOUT should be set, and the calls nfs41_proc_async_sequence, which only gets sent if the NFS4_RENEW_TIMEOUT flag is set. Then the nfs41_proc_async_sequence rpc_release function schedules another state remewal via nfs4_schedule_state_renewal. Without this change we can get into a state where an application stops accessing the NFSv4.1 share, state renewal calls stop due to the NFS4_RENEW_TIMEOUT flag _not_ being set. The only way to recover from this situation is with a clientid re-establishment, once the application resumes and the server has timed out the lease and so returns NFS4ERR_BAD_SESSION on the subsequent SEQUENCE operation. An example application: open, lock, write a file. sleep for 6 * lease (could be less) ulock, close. In the above example with NFSv4.1 delegations enabled, without this change, there are no OP_SEQUENCE state renewal calls during the sleep, and the clientid is recovered due to lease expiration on the close. This issue does not occur with NFSv4.1 delegations disabled, nor with NFSv4.0, with or without delegations enabled. Signed-off-by: Andy Adamson --- fs/nfs/nfs4proc.c | 2 +- fs/nfs/nfs4renewd.c | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 288be08..ed25f38 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -7349,7 +7349,7 @@ static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr int ret = 0; if ((renew_flags & NFS4_RENEW_TIMEOUT) == 0) - return 0; + return -EAGAIN; task = _nfs41_proc_sequence(clp, cred, false); if (IS_ERR(task)) ret = PTR_ERR(task); diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 1720d32..b00e1e2 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c @@ -88,16 +88,26 @@ nfs4_renew_state(struct work_struct *work) } nfs_expire_all_delegations(clp); } else { + int ret; + /* Queue an asynchronous RENEW. */ - ops->sched_state_renewal(clp, cred, renew_flags); + ret = ops->sched_state_renewal(clp, cred, renew_flags); put_rpccred(cred); - goto out_exp; + switch (ret) { + case 0: + default: + goto out_exp; + case -EAGAIN: + case -ENOMEM: + goto out_sched; + } } } else { dprintk("%s: failed to call renewd. Reason: lease not expired \n", __func__); spin_unlock(&clp->cl_lock); } +out_sched: nfs4_schedule_state_renewal(clp); out_exp: nfs_expire_unreferenced_delegations(clp);