Received: by 10.213.65.68 with SMTP id h4csp36094imn; Mon, 19 Mar 2018 18:43:05 -0700 (PDT) X-Google-Smtp-Source: AG47ELsOPca1Fx+gk87mX7LbjAQSyCLxPx65EsRk4PNuOqk2kr23EXHV1NeMzAJjrOKXNME7pD55 X-Received: by 10.98.153.204 with SMTP id t73mr3063852pfk.121.1521510185059; Mon, 19 Mar 2018 18:43:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521510185; cv=none; d=google.com; s=arc-20160816; b=Lktgyi34hAC/9vYJHWWG9bDRejomkTAVuxH8fYbowo+JPY0R3Gm+l3cx9vp+lyW5+o P39SX8QeBZE2pkEhcYe2Vnfn8nT3AQZoi9SDYoAMSGtM5fsvW8pA+x2jlLa3yeNDqUPt KN3zlH2l4wI46T37QMnhOobaRpPY6geKWhOfWVsiaOxm6TTxqlaciGWjNFRg7YM3nWwu QMxKnyEhkJ0YDvzaNOFGsYcHT82LDvEAFsWxtdWB33aqr1NopPOUYSZbT+2qgi2fKgfI te3Vg5Nv2k8ZbJ6A6Brpp0wdv7FinjUpVYa3RI8KbqMOV5a527ciWSmNfoEqWnEYBBXq o+VA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=IdSLSPiUU3RCgpuYapAHXw+qYrsfwJwMZs6bzc4Ood8=; b=ism+VNXngkF+KlmmV3/4plDWXOmn/qZRMClpn5z6LqQGzTYnyEAF3xT7Bmcf0TG9QE NcqiEGNXozj7wugmNo8j9hyErwEqi+bJ1c/ZqS/Um7f4G7cgjJD/cGMv9RVDeI63l5Xu InU6cbeC0SeLFDIMyxI7LP1lmEDR9ATP31V2MsTDXxNY+isokK8QupJOKs7lyhnqKXZ4 nfaSgc9piuFNz4V7CFpyRnlh/nbpibunHKcttiBACvv9TkgaTXY+r4T2mNZ1geO4i/k8 Z44TuTPEO/ohCyhpc47BWiYt/Cvt9w87uiRzj/EV580WR9ihNpsWZiWi0P6lofK6pN5F xh5w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n3si394089pgc.12.2018.03.19.18.42.51; Mon, 19 Mar 2018 18:43:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030659AbeCSSOK (ORCPT + 99 others); Mon, 19 Mar 2018 14:14:10 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:43978 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030637AbeCSSOC (ORCPT ); Mon, 19 Mar 2018 14:14:02 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 6E13C88D; Mon, 19 Mar 2018 18:14:01 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jan Kara , Sasha Levin Subject: [PATCH 4.4 052/134] reiserfs: Make cancel_old_flush() reliable Date: Mon, 19 Mar 2018 19:05:35 +0100 Message-Id: <20180319171856.867401254@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180319171849.024066323@linuxfoundation.org> References: <20180319171849.024066323@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jan Kara [ Upstream commit 71b0576bdb862e964a82c73327cdd1a249c53e67 ] Currently canceling of delayed work that flushes old data using cancel_old_flush() does not prevent work from being requeued. Thus in theory new work can be queued after cancel_old_flush() from reiserfs_freeze() has run. This will become larger problem once flush_old_commits() can requeue the work itself. Fix the problem by recording in sbi->work_queue that flushing work is canceled and should not be requeued. Signed-off-by: Jan Kara Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/reiserfs/journal.c | 2 +- fs/reiserfs/reiserfs.h | 1 + fs/reiserfs/super.c | 21 +++++++++++++++------ 3 files changed, 17 insertions(+), 7 deletions(-) --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -1961,7 +1961,7 @@ static int do_journal_release(struct rei * will be requeued because superblock is being shutdown and doesn't * have MS_ACTIVE set. */ - cancel_delayed_work_sync(&REISERFS_SB(sb)->old_work); + reiserfs_cancel_old_flush(sb); /* wait for all commits to finish */ cancel_delayed_work_sync(&SB_JOURNAL(sb)->j_work); --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h @@ -2948,6 +2948,7 @@ int reiserfs_allocate_list_bitmaps(struc struct reiserfs_list_bitmap *, unsigned int); void reiserfs_schedule_old_flush(struct super_block *s); +void reiserfs_cancel_old_flush(struct super_block *s); void add_save_link(struct reiserfs_transaction_handle *th, struct inode *inode, int truncate); int remove_save_link(struct inode *inode, int truncate); --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -90,7 +90,9 @@ static void flush_old_commits(struct wor s = sbi->s_journal->j_work_sb; spin_lock(&sbi->old_work_lock); - sbi->work_queued = 0; + /* Avoid clobbering the cancel state... */ + if (sbi->work_queued == 1) + sbi->work_queued = 0; spin_unlock(&sbi->old_work_lock); reiserfs_sync_fs(s, 1); @@ -117,21 +119,22 @@ void reiserfs_schedule_old_flush(struct spin_unlock(&sbi->old_work_lock); } -static void cancel_old_flush(struct super_block *s) +void reiserfs_cancel_old_flush(struct super_block *s) { struct reiserfs_sb_info *sbi = REISERFS_SB(s); - cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); spin_lock(&sbi->old_work_lock); - sbi->work_queued = 0; + /* Make sure no new flushes will be queued */ + sbi->work_queued = 2; spin_unlock(&sbi->old_work_lock); + cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); } static int reiserfs_freeze(struct super_block *s) { struct reiserfs_transaction_handle th; - cancel_old_flush(s); + reiserfs_cancel_old_flush(s); reiserfs_write_lock(s); if (!(s->s_flags & MS_RDONLY)) { @@ -152,7 +155,13 @@ static int reiserfs_freeze(struct super_ static int reiserfs_unfreeze(struct super_block *s) { + struct reiserfs_sb_info *sbi = REISERFS_SB(s); + reiserfs_allow_writes(s); + spin_lock(&sbi->old_work_lock); + /* Allow old_work to run again */ + sbi->work_queued = 0; + spin_unlock(&sbi->old_work_lock); return 0; } @@ -2187,7 +2196,7 @@ error_unlocked: if (sbi->commit_wq) destroy_workqueue(sbi->commit_wq); - cancel_delayed_work_sync(&REISERFS_SB(s)->old_work); + reiserfs_cancel_old_flush(s); reiserfs_free_bitmap_cache(s); if (SB_BUFFER_WITH_SB(s))