kill-the-BKL/reiserfs: only acquire the write lock once in reiserfs_dirty_inode
authorFrederic Weisbecker <fweisbec@gmail.com>
Tue, 14 Apr 2009 03:34:25 +0000 (05:34 +0200)
committerFrederic Weisbecker <fweisbec@gmail.com>
Mon, 14 Sep 2009 05:18:04 +0000 (07:18 +0200)
commitdc8f6d8936eb244eea452af689df5ee19e635206
treec93624678a2d2821c78048f6f7db19889eac5b3a
parent22c963addcf426bef97a43f6e601f985f8082ed5
kill-the-BKL/reiserfs: only acquire the write lock once in reiserfs_dirty_inode

Impact: fix a deadlock

reiserfs_dirty_inode() is the super_operations::dirty_inode() callback
of reiserfs. It can be called from different contexts where the write
lock can be already held.

But this function also grab the write lock (possibly recursively).
Subsequent release of the lock before sleep will actually not release
the lock if the caller of mark_inode_dirty() (which in turn calls
reiserfs_dirty_inode()) already owns the lock.

A typical case:

reiserfs_write_end() {
acquire_write_lock()
mark_inode_dirty() {
reiserfs_dirty_inode() {
reacquire_write_lock() {
journal_begin() {
do_journal_begin_r() {
/*
 * fail to release, still
 * one depth of lock
 */
release_write_lock()
reiserfs_wait_on_write_block() {
wait_event()

The event is usually provided by something which needs the write lock but
it hasn't been released.

We use reiserfs_write_lock_once() here to ensure we only grab the
write lock in one level.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Alessio Igor Bogani <abogani@texware.it>
Cc: Jeff Mahoney <jeffm@suse.com>
Cc: Chris Mason <chris.mason@oracle.com>
LKML-Reference: <1239680065-25013-4-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
fs/reiserfs/super.c