linux/fs/jbd2
Jan Kara 9837d8e982 jbd2: fix hung processes in jbd2_journal_lock_updates()
Toshiyuki Okajima found out that when running

for ((i=0; i < 100000; i++)); do
        if ((i%2 == 0)); then
                chattr +j /mnt/file
        else
                chattr -j /mnt/file
        fi
        echo "0" >> /mnt/file
done

process sometimes hangs indefinitely in jbd2_journal_lock_updates().

Toshiyuki identified that the following race happens:

jbd2_journal_lock_updates()            |jbd2_journal_stop()
---------------------------------------+---------------------------------------
 write_lock(&journal->j_state_lock)    |    .
 ++journal->j_barrier_count            |    .
 spin_lock(&tran->t_handle_lock)       |    .
 atomic_read(&tran->t_updates) //not 0 |
                                       | atomic_dec_and_test(&tran->t_updates)
                                       |    // t_updates = 0
                                       | wake_up(&journal->j_wait_updates)
 prepare_to_wait()                     |    // no process is woken up.
 spin_unlock(&tran->t_handle_lock)     |
 write_unlock(&journal->j_state_lock)  |
 schedule() // never return            |

We fix the problem by first calling prepare_to_wait() and only after that
checking t_updates in jbd2_journal_lock_updates().

Reported-and-analyzed-by: Toshiyuki Okajima <toshi.okajima@jp.fujitsu.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
2012-01-04 22:03:11 -05:00
..
checkpoint.c jbd2: use WRITE_SYNC in journal checkpoint 2011-06-27 12:36:29 -04:00
commit.c jbd2: clear revoked flag on buffers before a new transaction started 2011-12-28 17:46:46 -05:00
journal.c jbd2: Unify log messages in jbd2 code 2011-11-01 19:09:18 -04:00
Kconfig Revert "task_struct: make journal_info conditional" 2009-12-17 13:23:24 -08:00
Makefile [PATCH] jbd2: rename jbd2 symbols to avoid duplication of jbd symbols 2006-10-11 11:14:15 -07:00
recovery.c jbd2: Unify log messages in jbd2 code 2011-11-01 19:09:18 -04:00
revoke.c jbd2: clear revoked flag on buffers before a new transaction started 2011-12-28 17:46:46 -05:00
transaction.c jbd2: fix hung processes in jbd2_journal_lock_updates() 2012-01-04 22:03:11 -05:00