From patchwork Wed Sep 24 17:47:22 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olga Kornievskaia X-Patchwork-Id: 4969141 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 752E79F2F0 for ; Wed, 24 Sep 2014 17:47:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 914862025A for ; Wed, 24 Sep 2014 17:47:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 933762022D for ; Wed, 24 Sep 2014 17:47:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751645AbaIXRrX (ORCPT ); Wed, 24 Sep 2014 13:47:23 -0400 Received: from mail-ie0-f182.google.com ([209.85.223.182]:43638 "EHLO mail-ie0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750793AbaIXRrW (ORCPT ); Wed, 24 Sep 2014 13:47:22 -0400 Received: by mail-ie0-f182.google.com with SMTP id tp5so6804750ieb.13 for ; Wed, 24 Sep 2014 10:47:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:message-id:subject:from:to:content-type; bh=HDavm86zJA3y6J7Eu4FbWgfxfeBrZMRgT8gmT1y+oZc=; b=pVZNTLm9MDHgY6Op/UA5UMuuWE63D6Hi3vWbYtna9g3b3sbDJ2D0CLp1h4sPOPQpom R9f5eiGTaZlqRizuuI5riJJ8bk2rgjOtFECUQuC+bAnp/thxMOUq6nLVuZlpuQpai44u LN/wrcMs/KLsTd71Ao256ZrZZpg7hQQiArYCBpuovKjfJlvufIfDIUtZzjCl2sLiSg1Y JycjksGhPn0ecVg9XqzMursCLfIRxrUv6GfGImzFNfXrE3noMWPjtEBr4vDu5GNblsv/ 09VoJTChcr1ujZ2A/ETrAd+Es9l2q7vjVbXSI8NpRbTxaedA/khj2L6VnZVKHWqZNQ/x e33w== MIME-Version: 1.0 X-Received: by 10.43.160.71 with SMTP id mb7mr12753997icc.7.1411580842277; Wed, 24 Sep 2014 10:47:22 -0700 (PDT) Received: by 10.107.158.211 with HTTP; Wed, 24 Sep 2014 10:47:22 -0700 (PDT) Date: Wed, 24 Sep 2014 13:47:22 -0400 X-Google-Sender-Auth: QbdT_zEH4leqvOoknA-dO_ef37A Message-ID: Subject: nfs4_lock_delegation_recall() improperly handles errors such as ERROR_GRACE From: Olga Kornievskaia To: linux-nfs 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.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham 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 There exists a problem in the code that was easily reproducible prior to the commit b757144fd77cf5512f5b60179ba5ca8dcc5184b4 ("NFSv4 Be less aggressive about returning delegations"). The same code is used during delegation return and is still reproducible (with highly coordinated setup of triggering just the right actions). The problem lies in the call of nfs4_lock_delegation_recall(). In the nutshell, when the LOCK op gets an error such as ERR_GRACE, the error is unhanded which leaves the client in incorrect state assuming that it has 'successfully' acquired a lock that was locally acquired while holding a delegation. I believe the problem stems from the fact that nfs4_lock_delegation_recall(), unlike normal version of LOCK nfs4_proc_getlk(), lacks the do { handle_error(do_proc())} while(err) structure. I believe the problem should be fixed by something like the following: struct nfs_release_lockowner_data { Is this an acceptable solution? --- 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 6ca0c8e..78d088c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5936,11 +5936,12 @@ int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, struct nfs_server *server = NFS_SERVER(state->inode); int err; - err = nfs4_set_lock_state(state, fl); - if (err != 0) - return err; - err = _nfs4_do_setlk(state, F_SETLK, fl, NFS_LOCK_NEW); - return nfs4_handle_delegation_recall_error(server, state, stateid, err); + do { + err = nfs4_handle_delegation_recall_error(server, state, + stateid, _nfs4_do_setlk(state, F_SETLK, fl, + NFS_LOCK_NEW)); + } while (err == -EAGAIN); + return err; }