Received: by 10.213.65.68 with SMTP id h4csp1722047imn; Mon, 19 Mar 2018 11:26:16 -0700 (PDT) X-Google-Smtp-Source: AG47ELvONYkWBF5cii/MKEsEcRexnbUORSwLONPfTM5QzyiUoGSqfgqvLJPiN/PB4vVD/zxcrBFn X-Received: by 10.99.135.67 with SMTP id i64mr9830774pge.346.1521483976910; Mon, 19 Mar 2018 11:26:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521483976; cv=none; d=google.com; s=arc-20160816; b=ybUtUNFk/h9TXzTljXxbya5E8nvMq3sLK6LbacrBXqJ6qh2dAXlydq5SMdjaceGC5d dns3+RbzTMtKL6jKaks0Szii+HEa1+/wlej8YvmEH+Le3VnuP7XDT9PIw4DdN+7Qq+D1 ZBH1BGIoZbVKsKhC2ZdG8PkExLuLamYqGNixW05zxuH+DW4iauDLrX5+RgWY7Mmnlu7w DfeB3ymrDq0DBZkBHe8tv/LvV1HDgT3TAvVfWSZSyMh5mL3slkdoz5SPfYBZn7JGwKF3 Ga3OMm4Ag2BrLHWEfSa5lAsYGSoekHv+NnFABgDXdGfJ3ZBwdzLfpS++RfLw2jd7OxRg Y3yg== 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=r4nNVwm8LTLT4j0b3k4MpQCEefM7RWq3pgLgJ9sEdzU=; b=akD4kaN+GgOBEQfu7R5//dOEt/zLJJl0PuZWMlIIr1LGtPH1xy9EK3zC+qbxFDyo1+ fsB6CzDOp95ILT9AsVRCk8KHb3PJbCFOZdcLvTIKb2XlXgWvQ3YWGn+TDxm9sSqIG7LP kJE+8TCo37Lkzz/Bxy6cW/nFYyF60aXM9V0mDnAMugB6GZMrTci4U1zcI+KjFCg5zMkA a96mMgQDJkqzbBljhAwwzl5ds8nFP2FjlX/ZcG+Sr0lCBAQw+FTIfbS1mMF7KNxOU2na yQnquygVuUkbaA/u+jwtPki+QiwfTSnjovBXEU9qS61KLRgZObupAeSuEMvJtKSETghl Pxkg== 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 f14si293972pgn.824.2018.03.19.11.26.02; Mon, 19 Mar 2018 11:26:16 -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 S969665AbeCSSY0 (ORCPT + 99 others); Mon, 19 Mar 2018 14:24:26 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:49886 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S969639AbeCSSYU (ORCPT ); Mon, 19 Mar 2018 14:24:20 -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 DEAC9F46; Mon, 19 Mar 2018 18:24:19 +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.9 107/241] reiserfs: Make cancel_old_flush() reliable Date: Mon, 19 Mar 2018 19:06:12 +0100 Message-Id: <20180319180755.624505421@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180319180751.172155436@linuxfoundation.org> References: <20180319180751.172155436@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.9-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 @@ -1959,7 +1959,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; } @@ -2194,7 +2203,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))