diff options
author | Eric Sandeen <sandeen@redhat.com> | 2010-05-16 02:00:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-05-16 02:00:00 -0400 |
commit | 6b0310fbf087ad6e9e3b8392adca97cd77184084 (patch) | |
tree | 6c15fad6ca442d92e8075578a9b04811ca093bda /fs/ext4/super.c | |
parent | 256a453546f1cf2c29a639c79fe0d603761a8e25 (diff) |
ext4: don't return to userspace after freezing the fs with a mutex held
ext4_freeze() used jbd2_journal_lock_updates() which takes
the j_barrier mutex, and then returns to userspace. The
kernel does not like this:
================================================
[ BUG: lock held when returning to user space! ]
------------------------------------------------
lvcreate/1075 is leaving the kernel with locks still held!
1 lock held by lvcreate/1075:
#0: (&journal->j_barrier){+.+...}, at: [<ffffffff811c6214>]
jbd2_journal_lock_updates+0xe1/0xf0
Use vfs_check_frozen() added to ext4_journal_start_sb() and
ext4_force_commit() instead.
Addresses-Red-Hat-Bugzilla: #568503
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e14d22c170d5..00d09f58f188 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -241,6 +241,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | |||
241 | if (sb->s_flags & MS_RDONLY) | 241 | if (sb->s_flags & MS_RDONLY) |
242 | return ERR_PTR(-EROFS); | 242 | return ERR_PTR(-EROFS); |
243 | 243 | ||
244 | vfs_check_frozen(sb, SB_FREEZE_WRITE); | ||
244 | /* Special case here: if the journal has aborted behind our | 245 | /* Special case here: if the journal has aborted behind our |
245 | * backs (eg. EIO in the commit thread), then we still need to | 246 | * backs (eg. EIO in the commit thread), then we still need to |
246 | * take the FS itself readonly cleanly. */ | 247 | * take the FS itself readonly cleanly. */ |
@@ -3485,8 +3486,10 @@ int ext4_force_commit(struct super_block *sb) | |||
3485 | return 0; | 3486 | return 0; |
3486 | 3487 | ||
3487 | journal = EXT4_SB(sb)->s_journal; | 3488 | journal = EXT4_SB(sb)->s_journal; |
3488 | if (journal) | 3489 | if (journal) { |
3490 | vfs_check_frozen(sb, SB_FREEZE_WRITE); | ||
3489 | ret = ext4_journal_force_commit(journal); | 3491 | ret = ext4_journal_force_commit(journal); |
3492 | } | ||
3490 | 3493 | ||
3491 | return ret; | 3494 | return ret; |
3492 | } | 3495 | } |
@@ -3535,18 +3538,16 @@ static int ext4_freeze(struct super_block *sb) | |||
3535 | * the journal. | 3538 | * the journal. |
3536 | */ | 3539 | */ |
3537 | error = jbd2_journal_flush(journal); | 3540 | error = jbd2_journal_flush(journal); |
3538 | if (error < 0) { | 3541 | if (error < 0) |
3539 | out: | 3542 | goto out; |
3540 | jbd2_journal_unlock_updates(journal); | ||
3541 | return error; | ||
3542 | } | ||
3543 | 3543 | ||
3544 | /* Journal blocked and flushed, clear needs_recovery flag. */ | 3544 | /* Journal blocked and flushed, clear needs_recovery flag. */ |
3545 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3545 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
3546 | error = ext4_commit_super(sb, 1); | 3546 | error = ext4_commit_super(sb, 1); |
3547 | if (error) | 3547 | out: |
3548 | goto out; | 3548 | /* we rely on s_frozen to stop further updates */ |
3549 | return 0; | 3549 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
3550 | return error; | ||
3550 | } | 3551 | } |
3551 | 3552 | ||
3552 | /* | 3553 | /* |
@@ -3563,7 +3564,6 @@ static int ext4_unfreeze(struct super_block *sb) | |||
3563 | EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3564 | EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
3564 | ext4_commit_super(sb, 1); | 3565 | ext4_commit_super(sb, 1); |
3565 | unlock_super(sb); | 3566 | unlock_super(sb); |
3566 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
3567 | return 0; | 3567 | return 0; |
3568 | } | 3568 | } |
3569 | 3569 | ||