Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp2923060iog; Mon, 20 Jun 2022 07:34:37 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uHDnjT950SzQ25NNK73mWHchJxiPDVmrXzUe06mdr32wjY/X+J68lZW6niz1MFueEntKyR X-Received: by 2002:a05:6402:2753:b0:431:9c8b:5635 with SMTP id z19-20020a056402275300b004319c8b5635mr29821917edd.152.1655735677204; Mon, 20 Jun 2022 07:34:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655735677; cv=none; d=google.com; s=arc-20160816; b=HoH8VQKtnvxgMOAY6MLIthazV3ipLFmB5r0VtaBWvDnOyRedNIf2Bg9JC+HtcO/N+K 6UjzDZTR3HTjKdUL58fu1mILB+OcNZ+K3JX9b3x46sII62i4/CQ1dCOCML+VoQTUbmzH SPa/4PZrTAUrrFfIbLJap4a4QFcQu6ozV/sbBB2B+/2Ojbh26XiIZluG10mT6fDhEl89 JgqDgGx0Aplcg6/v1w4WodNMT9USDkNq+L5nSjm2tCy7iSBClUOnmzSmv9nVW3ASvl/b vEd8ysNyeUsKLDv6uuwycNGeg42S4ICVR6SDz1b0B2ZmoeBI1GttkY0QosDNetwKE0fs xHYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=eJkEfG+eEaZADIlciq38x/i2XJiGNVVsrnmnV41Wmzg=; b=iswKeuHeiOzCUHoRKoz0H97Sf6KRf2vtNtijAaOnFyewTOazf0NNz2evgxQy/Ir61q bCeS8NMi+ocwmMRjj80LrptfP97VlQmgvLZOeP9Zfeg9XjR3CYb8RoGjs7gDX2SRYTue TG21+XcyaWq3WJRkjVpkHguYNPz0+VC7LGwlLlEMbftuQnwZMRzJP/zbAVvYrumIbobb vD+nWhRFsQZKn3oohXYb50x1i7+V0cH114tA0vfXnQ8C8iW5tTMfCIBqZDVEGzrAjy82 2Dt+DORaRE7cnYhatosW6nWGlEKl1rjpH41kGSkCAz+IUlghNbmeElDIeDyUOQ/D28fw u3Og== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Z75MrIIq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e6-20020a056402190600b004351fb8291fsi14272724edz.577.2022.06.20.07.34.11; Mon, 20 Jun 2022 07:34:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Z75MrIIq; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245708AbiFTNL4 (ORCPT + 99 others); Mon, 20 Jun 2022 09:11:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245579AbiFTNJP (ORCPT ); Mon, 20 Jun 2022 09:09:15 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1ED961583F; Mon, 20 Jun 2022 06:03:23 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 63A8561575; Mon, 20 Jun 2022 13:02:15 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 483BAC341C5; Mon, 20 Jun 2022 13:02:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1655730134; bh=8TKhB7Zsach2lBIDLfoZ8n/XaDkjqGPuFKnxioYkWRA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z75MrIIqFbyWGlwZL/gIV4csg7U6dBWa9auOEpHINU9asV2lI953pHBdEYCxG7JBf sU/I7MDcmaM0icZWw+1ntq1TscUxMUVFKpLkSOqZ05M17oxeQNT/lDO9etoVY2kbxW xgIXObjqWl0MHGNh0K4JL7t58sHj2LihSJ/XdfOE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Trond Myklebust , Anna Schumaker , Sasha Levin Subject: [PATCH 5.10 36/84] pNFS: Avoid a live lock condition in pnfs_update_layout() Date: Mon, 20 Jun 2022 14:50:59 +0200 Message-Id: <20220620124721.960052175@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620124720.882450983@linuxfoundation.org> References: <20220620124720.882450983@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Trond Myklebust [ Upstream commit 880265c77ac415090090d1fe72a188fee71cb458 ] If we're about to send the first layoutget for an empty layout, we want to make sure that we drain out the existing pending layoutget calls first. The reason is that these layouts may have been already implicitly returned to the server by a recall to which the client gave a NFS4ERR_NOMATCHING_LAYOUT response. The problem is that wait_var_event_killable() could in principle see the plh_outstanding count go back to '1' when the first process to wake up starts sending a new layoutget. If it fails to get a layout, then this loop can continue ad infinitum... Fixes: 0b77f97a7e42 ("NFSv4/pnfs: Fix layoutget behaviour after invalidation") Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker Signed-off-by: Sasha Levin --- fs/nfs/callback_proc.c | 1 + fs/nfs/pnfs.c | 15 +++++++++------ fs/nfs/pnfs.h | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index a5209643ac36..bfdd21224073 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -283,6 +283,7 @@ static u32 initiate_file_draining(struct nfs_client *clp, rv = NFS4_OK; break; case -ENOENT: + set_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags); /* Embrace your forgetfulness! */ rv = NFS4ERR_NOMATCHING_LAYOUT; diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 69bb50d0ee3f..21436721745b 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -469,6 +469,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo, pnfs_clear_lseg_state(lseg, lseg_list); pnfs_clear_layoutreturn_info(lo); pnfs_free_returned_lsegs(lo, lseg_list, &range, 0); + set_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags); if (test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags) && !test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags)) pnfs_clear_layoutreturn_waitbit(lo); @@ -1923,8 +1924,9 @@ static void nfs_layoutget_begin(struct pnfs_layout_hdr *lo) static void nfs_layoutget_end(struct pnfs_layout_hdr *lo) { - if (atomic_dec_and_test(&lo->plh_outstanding)) - wake_up_var(&lo->plh_outstanding); + if (atomic_dec_and_test(&lo->plh_outstanding) && + test_and_clear_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags)) + wake_up_bit(&lo->plh_flags, NFS_LAYOUT_DRAIN); } static bool pnfs_is_first_layoutget(struct pnfs_layout_hdr *lo) @@ -2031,11 +2033,11 @@ pnfs_update_layout(struct inode *ino, * If the layout segment list is empty, but there are outstanding * layoutget calls, then they might be subject to a layoutrecall. */ - if ((list_empty(&lo->plh_segs) || !pnfs_layout_is_valid(lo)) && + if (test_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags) && atomic_read(&lo->plh_outstanding) != 0) { spin_unlock(&ino->i_lock); - lseg = ERR_PTR(wait_var_event_killable(&lo->plh_outstanding, - !atomic_read(&lo->plh_outstanding))); + lseg = ERR_PTR(wait_on_bit(&lo->plh_flags, NFS_LAYOUT_DRAIN, + TASK_KILLABLE)); if (IS_ERR(lseg)) goto out_put_layout_hdr; pnfs_put_layout_hdr(lo); @@ -2414,7 +2416,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp) goto out_forget; } - if (!pnfs_layout_is_valid(lo) && !pnfs_is_first_layoutget(lo)) + if (test_bit(NFS_LAYOUT_DRAIN, &lo->plh_flags) && + !pnfs_is_first_layoutget(lo)) goto out_forget; if (nfs4_stateid_match_other(&lo->plh_stateid, &res->stateid)) { diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h index 11d9ed9addc0..a7cf84a6673b 100644 --- a/fs/nfs/pnfs.h +++ b/fs/nfs/pnfs.h @@ -107,6 +107,7 @@ enum { NFS_LAYOUT_FIRST_LAYOUTGET, /* Serialize first layoutget */ NFS_LAYOUT_INODE_FREEING, /* The inode is being freed */ NFS_LAYOUT_HASHED, /* The layout visible */ + NFS_LAYOUT_DRAIN, }; enum layoutdriver_policy_flags { -- 2.35.1