Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp152302pxb; Mon, 13 Sep 2021 15:38:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxP8DHW3HlY6ricjhnhHnNeklio32Jc3WB8pjWDQrYVvUsMFDJDPiSom+O/k3o9op1RaTwx X-Received: by 2002:a92:cbce:: with SMTP id s14mr9658481ilq.20.1631572687006; Mon, 13 Sep 2021 15:38:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631572686; cv=none; d=google.com; s=arc-20160816; b=CSgYZ0VK0ROOYr1mxtNicSqGGK64MeTky4ipG6K2Fh14eQ2lGAUQ1aNoWesjLunXzs lbhPWDX9g9nw3dblkuh11A4CQf22bFIYYXOhKfZ7BgJ+UZBMvtzQejpT0E6OIqFLNB98 TG34NIw+dargn3pg1Kyf6AsmKRKfW1734HmIjXGnYO6gEX2m0x/7o0jGxpNWxNHpp+bQ kLb0GA8iAvbNz0kPZHMdZBL4i1PE+XWP9bLb9L9z5QZOS6onNqJWfaU9XM9oPKC9pazz zIfRm3zpMxY/cnKDKWJIwhlMFPAgG8Ai9Qp8P7FF/w9PlqhaEfegnvBBmZzMx7xBpzV1 3aCg== 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=vgjc0l44LCdSKxIFDC+JhR481oFQT2HS5aqQkh+afQ4=; b=ogeOJpYDzTNyPqN9ghiZiM4pwJwVa5hCQQWDe22+Olr3X3DDTVULC0Ug/p8DCZxmdv CrKc0wW/cTjr0lPGnsk61LSsTcPtVcoWH/6TZFdU6EEKbGEpTqsGOY+Hsf7tC7LcMeMl +8Fm5uX/WHcG3PX7J5criRdHf7+nFQ5i6cYtrmWNqmlloXs7ykHH+5GPRdha/pjYNGR2 qjLbO1gH+aapTeNH05wA9n5vaWAcF7v2a7Qa1OlEnRnfsUAoRSIXOPDlYMFSSbmP/9z3 FhD25YSM2RsHoFVHCvYUgTLx+KiIyGVevIkcoGRhHHMh392C8rFwJQ59HyT+TCnDo4Bh qPjA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="QlEOh/JS"; 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=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id x8si9121224iom.11.2021.09.13.15.37.55; Mon, 13 Sep 2021 15:38:06 -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=@linuxfoundation.org header.s=korg header.b="QlEOh/JS"; 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=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242728AbhIMOMx (ORCPT + 99 others); Mon, 13 Sep 2021 10:12:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:60400 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345063AbhIMOJo (ORCPT ); Mon, 13 Sep 2021 10:09:44 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 5B89E61A89; Mon, 13 Sep 2021 13:41:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1631540491; bh=kBsgrVDe7zt/GZ0Pd3XptA/5U+L9g86/TTGBqjTSM3w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QlEOh/JS++eyoviYT/D+BEgi4X31ySL0bAxX9327Vbe3Udmvvwc0x1Lei0CaqaBSZ 4WGrF4N4592o9CFZktuKoWewR7b2cwbGUhL13rryMzApR1UpmOR2GXaqYdd+1LP2/J Ej+ThuonNYMVCGfWWz1uRxI1rSeBRj4OOl+A8Ubk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Bob Peterson , Sasha Levin Subject: [PATCH 5.13 215/300] gfs2: init system threads before freeze lock Date: Mon, 13 Sep 2021 15:14:36 +0200 Message-Id: <20210913131116.620449785@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210913131109.253835823@linuxfoundation.org> References: <20210913131109.253835823@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Bob Peterson [ Upstream commit a28dc123fa66ba7f3eca7cffc4b01d96bfd35c27 ] Patch 96b1454f2e ("gfs2: move freeze glock outside the make_fs_rw and _ro functions") changed the gfs2 mount sequence so that it holds the freeze lock before calling gfs2_make_fs_rw. Before this patch, gfs2_make_fs_rw called init_threads to initialize the quotad and logd threads. That is a problem if the system needs to withdraw due to IO errors early in the mount sequence, for example, while initializing the system statfs inode: 1. An IO error causes the statfs glock to not sync properly after recovery, and leaves items on the ail list. 2. The leftover items on the ail list causes its do_xmote call to fail, which makes it want to withdraw. But since the glock code cannot withdraw (because the withdraw sequence uses glocks) it relies upon the logd daemon to initiate the withdraw. 3. The withdraw can never be performed by the logd daemon because all this takes place before the logd daemon is started. This patch moves function init_threads from super.c to ops_fstype.c and it changes gfs2_fill_super to start its threads before holding the freeze lock, and if there's an error, stop its threads after releasing it. This allows the logd to run unblocked by the freeze lock. Thus, the logd daemon can perform its withdraw sequence properly. Fixes: 96b1454f2e8e ("gfs2: move freeze glock outside the make_fs_rw and _ro functions") Signed-off-by: Bob Peterson Signed-off-by: Sasha Levin --- fs/gfs2/ops_fstype.c | 42 ++++++++++++++++++++++++++++++ fs/gfs2/super.c | 61 +++++--------------------------------------- 2 files changed, 48 insertions(+), 55 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index bd3b3be1a473..ca76e3b8792c 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1089,6 +1089,34 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp) kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp); } +static int init_threads(struct gfs2_sbd *sdp) +{ + struct task_struct *p; + int error = 0; + + p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); + if (IS_ERR(p)) { + error = PTR_ERR(p); + fs_err(sdp, "can't start logd thread: %d\n", error); + return error; + } + sdp->sd_logd_process = p; + + p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); + if (IS_ERR(p)) { + error = PTR_ERR(p); + fs_err(sdp, "can't start quotad thread: %d\n", error); + goto fail; + } + sdp->sd_quotad_process = p; + return 0; + +fail: + kthread_stop(sdp->sd_logd_process); + sdp->sd_logd_process = NULL; + return error; +} + /** * gfs2_fill_super - Read in superblock * @sb: The VFS superblock @@ -1217,6 +1245,14 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) goto fail_per_node; } + if (!sb_rdonly(sb)) { + error = init_threads(sdp); + if (error) { + gfs2_withdraw_delayed(sdp); + goto fail_per_node; + } + } + error = gfs2_freeze_lock(sdp, &freeze_gh, 0); if (error) goto fail_per_node; @@ -1226,6 +1262,12 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) gfs2_freeze_unlock(&freeze_gh); if (error) { + if (sdp->sd_quotad_process) + kthread_stop(sdp->sd_quotad_process); + sdp->sd_quotad_process = NULL; + if (sdp->sd_logd_process) + kthread_stop(sdp->sd_logd_process); + sdp->sd_logd_process = NULL; fs_err(sdp, "can't make FS RW: %d\n", error); goto fail_per_node; } diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 4d4ceb0b6903..2bdbba5ea8d7 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -119,34 +119,6 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd) return 0; } -static int init_threads(struct gfs2_sbd *sdp) -{ - struct task_struct *p; - int error = 0; - - p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); - if (IS_ERR(p)) { - error = PTR_ERR(p); - fs_err(sdp, "can't start logd thread: %d\n", error); - return error; - } - sdp->sd_logd_process = p; - - p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); - if (IS_ERR(p)) { - error = PTR_ERR(p); - fs_err(sdp, "can't start quotad thread: %d\n", error); - goto fail; - } - sdp->sd_quotad_process = p; - return 0; - -fail: - kthread_stop(sdp->sd_logd_process); - sdp->sd_logd_process = NULL; - return error; -} - /** * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one * @sdp: the filesystem @@ -161,26 +133,17 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) struct gfs2_log_header_host head; int error; - error = init_threads(sdp); - if (error) { - gfs2_withdraw_delayed(sdp); - return error; - } - j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); - if (gfs2_withdrawn(sdp)) { - error = -EIO; - goto fail; - } + if (gfs2_withdrawn(sdp)) + return -EIO; error = gfs2_find_jhead(sdp->sd_jdesc, &head, false); if (error || gfs2_withdrawn(sdp)) - goto fail; + return error; if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { gfs2_consist(sdp); - error = -EIO; - goto fail; + return -EIO; } /* Initialize some head of the log stuff */ @@ -188,20 +151,8 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) gfs2_log_pointers_init(sdp, head.lh_blkno); error = gfs2_quota_init(sdp); - if (error || gfs2_withdrawn(sdp)) - goto fail; - - set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); - - return 0; - -fail: - if (sdp->sd_quotad_process) - kthread_stop(sdp->sd_quotad_process); - sdp->sd_quotad_process = NULL; - if (sdp->sd_logd_process) - kthread_stop(sdp->sd_logd_process); - sdp->sd_logd_process = NULL; + if (!error && !gfs2_withdrawn(sdp)) + set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); return error; } -- 2.30.2