Jesse Keating 7a32965
[PATCH] ext4: fix freeze deadlock under IO
Jesse Keating 7a32965
Jesse Keating 7a32965
Commit 6b0310fbf087ad6 caused a regression resulting in deadlocks
Jesse Keating 7a32965
when freezing a filesystem which had active IO; the vfs_check_frozen
Jesse Keating 7a32965
level (SB_FREEZE_WRITE) did not let the freeze-related IO syncing
Jesse Keating 7a32965
through.  Duh.
Jesse Keating 7a32965
Jesse Keating 7a32965
Changing the test to FREEZE_TRANS should let the normal freeze
Jesse Keating 7a32965
syncing get through the fs, but still block any transactions from
Jesse Keating 7a32965
starting once the fs is completely frozen.
Jesse Keating 7a32965
Jesse Keating 7a32965
I tested this by running fsstress in the background while periodically
Jesse Keating 7a32965
snapshotting the fs and running fsck on the result.  I ran into
Jesse Keating 7a32965
occasional deadlocks, but different ones.  I think this is a
Jesse Keating 7a32965
fine fix for the problem at hand, and the other deadlocky things
Jesse Keating 7a32965
will need more investigation.
Jesse Keating 7a32965
Jesse Keating 7a32965
Reported-by: Phillip Susi <psusi@cfl.rr.com>
Jesse Keating 7a32965
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Jesse Keating 7a32965
---
Jesse Keating 7a32965
Jesse Keating 7a32965
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
Jesse Keating 7a32965
index 4e8983a..a45ced9 100644
Jesse Keating 7a32965
--- a/fs/ext4/super.c
Jesse Keating 7a32965
+++ b/fs/ext4/super.c
Jesse Keating 7a32965
@@ -241,7 +241,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
Jesse Keating 7a32965
 	if (sb->s_flags & MS_RDONLY)
Jesse Keating 7a32965
 		return ERR_PTR(-EROFS);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	vfs_check_frozen(sb, SB_FREEZE_WRITE);
Jesse Keating 7a32965
+	vfs_check_frozen(sb, SB_FREEZE_TRANS);
Jesse Keating 7a32965
 	/* Special case here: if the journal has aborted behind our
Jesse Keating 7a32965
 	 * backs (eg. EIO in the commit thread), then we still need to
Jesse Keating 7a32965
 	 * take the FS itself readonly cleanly. */
Jesse Keating 7a32965
@@ -3491,7 +3491,7 @@ int ext4_force_commit(struct super_block *sb)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	journal = EXT4_SB(sb)->s_journal;
Jesse Keating 7a32965
 	if (journal) {
Jesse Keating 7a32965
-		vfs_check_frozen(sb, SB_FREEZE_WRITE);
Jesse Keating 7a32965
+		vfs_check_frozen(sb, SB_FREEZE_TRANS);
Jesse Keating 7a32965
 		ret = ext4_journal_force_commit(journal);
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
Jesse Keating 7a32965
Jesse Keating 7a32965