diff options
author | Josef Bacik <josef@redhat.com> | 2009-12-08 21:48:58 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-12-08 21:48:58 -0500 |
commit | d4edac314e9ad0b21ba20ba8bc61b61f186f79e1 (patch) | |
tree | af44b291976308b9db6c215cb2dc03bbe020d6fc /fs/ext4 | |
parent | b9a4207d5e911b938f73079a83cc2ae10524ec7f (diff) |
ext4: wait for log to commit when umounting
There is a potential race when a transaction is committing right when
the file system is being umounting. This could reduce in a race
because EXT4_SB(sb)->s_group_info could be freed in ext4_put_super
before the commit code calls a callback so the mballoc code can
release freed blocks in the transaction, resulting in a panic trying
to access the freed s_group_info.
The fix is to wait for the transaction to finish committing before we
shutdown the multiblock allocator.
Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/super.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 30476daf966e..8ab0c9518473 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -603,10 +603,6 @@ static void ext4_put_super(struct super_block *sb) | |||
603 | if (sb->s_dirt) | 603 | if (sb->s_dirt) |
604 | ext4_commit_super(sb, 1); | 604 | ext4_commit_super(sb, 1); |
605 | 605 | ||
606 | ext4_release_system_zone(sb); | ||
607 | ext4_mb_release(sb); | ||
608 | ext4_ext_release(sb); | ||
609 | ext4_xattr_put_super(sb); | ||
610 | if (sbi->s_journal) { | 606 | if (sbi->s_journal) { |
611 | err = jbd2_journal_destroy(sbi->s_journal); | 607 | err = jbd2_journal_destroy(sbi->s_journal); |
612 | sbi->s_journal = NULL; | 608 | sbi->s_journal = NULL; |
@@ -614,6 +610,12 @@ static void ext4_put_super(struct super_block *sb) | |||
614 | ext4_abort(sb, __func__, | 610 | ext4_abort(sb, __func__, |
615 | "Couldn't clean up the journal"); | 611 | "Couldn't clean up the journal"); |
616 | } | 612 | } |
613 | |||
614 | ext4_release_system_zone(sb); | ||
615 | ext4_mb_release(sb); | ||
616 | ext4_ext_release(sb); | ||
617 | ext4_xattr_put_super(sb); | ||
618 | |||
617 | if (!(sb->s_flags & MS_RDONLY)) { | 619 | if (!(sb->s_flags & MS_RDONLY)) { |
618 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 620 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
619 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 621 | es->s_state = cpu_to_le16(sbi->s_mount_state); |