Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1058463pxk; Mon, 31 Aug 2020 08:41:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyiSUhSZCm/xkd2FJjY9ur3NEyuRmvARzDgI2Z9Qlqfvr8J6eLZ6xKayIDAHm3Bucei5BYQ X-Received: by 2002:a05:6402:8d3:: with SMTP id d19mr1764350edz.68.1598888515405; Mon, 31 Aug 2020 08:41:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598888515; cv=none; d=google.com; s=arc-20160816; b=y/V/jOwEDjdRyw4my47DfEeCrUBJf/gx+4NJVXp1XzqHHrXZMp5Tlmtpg483uXwrbS AThUcM3x6a9Nyi2PWJXD3jZLjP/T8zXpDpi/Z1JzNuCjoxaT+bCSX9w3DwT1moGnvo2i FKf2aY92PvvgbZVfNQ9G9BFYy2APCeyvXv5TKGYlf7jQfXJQf4Vr0S9zxTvdJRirKQdk oOKmPwPDRUTCMxG2dYLVWil4YnISnMojcrwRD/02Gtz2QeP4ydHn1XAyQWdDAuG+HV6R sogqvydRcwSQqVFuEKyFoo4+o1RFvkRE1KFgsmXAsm4q5WemWupI/TgfW8ItH0lmUM7U ctDw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ddrpaewFbCPbw5pG4gIfOKEhOYpNKwk0n0tbMhSBntM=; b=eVctSx0+vgy02MohMWJoCiq1d/dEVJ3OIoAmsxAbVZktu3n8wh30g4ekKrF9RoSviv KpQx81sFCSNGM1Oz25EWT5A5UX82oL8h58Er8ZrvzNneBDH7Y03TsnnLSA6qJXYF3fRy IorwHzio5zVivZ4Rjwq4IEoGkogZP4le/PuQAaGnb8SfUPRnPqRN4B5BijO4e66MbNUo 0SeHTYMvEzBIpca1dtGXCkCxM4XdoskXpf0o6a6kQd9xW/FSht0IrqO/2qXKpuSNMar8 cZqqO5Fy4kcoaN3T3tFPw8q7DerqlT6MZS/fwQp/X1o5iyEvOtW0kZTHpOPKAyoDa3Qk NEjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IBDVHeU5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l26si6035232eje.138.2020.08.31.08.41.32; Mon, 31 Aug 2020 08:41:55 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IBDVHeU5; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728756AbgHaPjd (ORCPT + 99 others); Mon, 31 Aug 2020 11:39:33 -0400 Received: from mail.kernel.org ([198.145.29.99]:39328 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728531AbgHaPaI (ORCPT ); Mon, 31 Aug 2020 11:30:08 -0400 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CD863214D8; Mon, 31 Aug 2020 15:30:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1598887807; bh=EIDdbwiV7I3/UvfbBAlS1QNVUgyFXb53fT0NauxxnSQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IBDVHeU58ZlK3PWD/zPuCf+acmwQ/hysdo+5U5DMhrdXThNz/6ENZLjbgSL9F+x4z /7iBtytC2OqLhYz95KBXpru+dexTn29ukpWi9YMv4FEfZ4PlB7S+L6/N85L1FI1OmI mpVasiW9MbBcQz50WZvwmt1P4NSpp28OnLjOAGHI= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Bob Peterson , Andreas Gruenbacher , Sasha Levin , cluster-devel@redhat.com Subject: [PATCH AUTOSEL 5.8 22/42] gfs2: add some much needed cleanup for log flushes that fail Date: Mon, 31 Aug 2020 11:29:14 -0400 Message-Id: <20200831152934.1023912-22-sashal@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200831152934.1023912-1-sashal@kernel.org> References: <20200831152934.1023912-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Bob Peterson [ Upstream commit 462582b99b6079a6fbcdfc65bac49f5c2a27cfff ] When a log flush fails due to io errors, it signals the failure but does not clean up after itself very well. This is because buffers are added to the transaction tr_buf and tr_databuf queue, but the io error causes gfs2_log_flush to bypass the "after_commit" functions responsible for dequeueing the bd elements. If the bd elements are added to the ail list before the error, function ail_drain takes care of dequeueing them. But if they haven't gotten that far, the elements are forgotten and make the transactions unable to be freed. This patch introduces new function trans_drain which drains the bd elements from the transaction so they can be freed properly. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher Signed-off-by: Sasha Levin --- fs/gfs2/log.c | 31 +++++++++++++++++++++++++++++++ fs/gfs2/trans.c | 1 + 2 files changed, 32 insertions(+) diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index a76e55bc28ebf..27f467a0f008e 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -901,6 +901,36 @@ static void empty_ail1_list(struct gfs2_sbd *sdp) } } +/** + * drain_bd - drain the buf and databuf queue for a failed transaction + * @tr: the transaction to drain + * + * When this is called, we're taking an error exit for a log write that failed + * but since we bypassed the after_commit functions, we need to remove the + * items from the buf and databuf queue. + */ +static void trans_drain(struct gfs2_trans *tr) +{ + struct gfs2_bufdata *bd; + struct list_head *head; + + if (!tr) + return; + + head = &tr->tr_buf; + while (!list_empty(head)) { + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); + kmem_cache_free(gfs2_bufdata_cachep, bd); + } + head = &tr->tr_databuf; + while (!list_empty(head)) { + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); + kmem_cache_free(gfs2_bufdata_cachep, bd); + } +} + /** * gfs2_log_flush - flush incore transaction(s) * @sdp: the filesystem @@ -1005,6 +1035,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) out: if (gfs2_withdrawn(sdp)) { + trans_drain(tr); /** * If the tr_list is empty, we're withdrawing during a log * flush that targets a transaction, but the transaction was diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index a3dfa3aa87ad9..d897dd73c5999 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -52,6 +52,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, tr->tr_reserved += gfs2_struct2blk(sdp, revokes); INIT_LIST_HEAD(&tr->tr_databuf); INIT_LIST_HEAD(&tr->tr_buf); + INIT_LIST_HEAD(&tr->tr_list); INIT_LIST_HEAD(&tr->tr_ail1_list); INIT_LIST_HEAD(&tr->tr_ail2_list); -- 2.25.1