kernel-ark/fs/jbd
Jan Kara bb189247f3 jbd: Fix oops in journal_remove_journal_head()
journal_remove_journal_head() can oops when trying to access journal_head
returned by bh2jh(). This is caused for example by the following race:

	TASK1					TASK2
  journal_commit_transaction()
    ...
    processing t_forget list
      __journal_refile_buffer(jh);
      if (!jh->b_transaction) {
        jbd_unlock_bh_state(bh);
					journal_try_to_free_buffers()
					  journal_grab_journal_head(bh)
					  jbd_lock_bh_state(bh)
					  __journal_try_to_free_buffer()
					  journal_put_journal_head(jh)
        journal_remove_journal_head(bh);

journal_put_journal_head() in TASK2 sees that b_jcount == 0 and buffer is not
part of any transaction and thus frees journal_head before TASK1 gets to doing
so. Note that even buffer_head can be released by try_to_free_buffers() after
journal_put_journal_head() which adds even larger opportunity for oops (but I
didn't see this happen in reality).

Fix the problem by making transactions hold their own journal_head reference
(in b_jcount). That way we don't have to remove journal_head explicitely via
journal_remove_journal_head() and instead just remove journal_head when
b_jcount drops to zero. The result of this is that [__]journal_refile_buffer(),
[__]journal_unfile_buffer(), and __journal_remove_checkpoint() can free
journal_head which needs modification of a few callers. Also we have to be
careful because once journal_head is removed, buffer_head might be freed as
well. So we have to get our own buffer_head reference where it matters.

Signed-off-by: Jan Kara <jack@suse.cz>
2011-06-27 11:44:37 +02:00
..
checkpoint.c jbd: Fix oops in journal_remove_journal_head() 2011-06-27 11:44:37 +02:00
commit.c jbd: Fix oops in journal_remove_journal_head() 2011-06-27 11:44:37 +02:00
journal.c jbd: Fix oops in journal_remove_journal_head() 2011-06-27 11:44:37 +02:00
Kconfig Revert "task_struct: make journal_info conditional" 2009-12-17 13:23:24 -08:00
Makefile
recovery.c jbd: Move debug message into #ifdef area 2010-10-28 01:30:01 +02:00
revoke.c Fix common misspellings 2011-03-31 11:26:23 -03:00
transaction.c jbd: Fix oops in journal_remove_journal_head() 2011-06-27 11:44:37 +02:00