Patch "reiserfs: Make cancel_old_flush() reliable" has been added to the 3.18-stable tree
This is a note to let you know that I've just added the patch titled
reiserfs: Make cancel_old_flush() reliable
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
reiserfs-make-cancel_old_flush-reliable.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Mar 19 10:11:52 CET 2018
From: Jan Kara <[email protected]>
Date: Wed, 5 Apr 2017 14:09:48 +0200
Subject: reiserfs: Make cancel_old_flush() reliable
From: Jan Kara <[email protected]>
[ 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.
--- fs/reiserfs/journal.c | 2 +- fs/reiserfs/reiserfs.h | 1 + fs/reiserfs/super.c | 21 +++++++++++++++------ 3 files changed, 17 insertions(+), 7 deletions(-)
fs/reiserfs/journal.c +1 -1
@@ -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);
fs/reiserfs/reiserfs.h +1 -0
@@ -2946,6 +2946,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);
fs/reiserfs/super.c +15 -6
@@ -89,7 +89,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 );
@@ -116,21 +118,22 @@ void reiserfs_schedule_old_flush(structspin_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 )) {
@@ -151,7 +154,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 ; }
@@ -2164,7 +2173,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))
Patches currently in stable-queue which might be from [email protected] are
queue-3.18/reiserfs-make-cancel_old_flush-reliable.patch