• Frederic Weisbecker's avatar
    kill-the-BKL/reiserfs: only acquire the write lock once in reiserfs_dirty_inode · dc8f6d89
    Frederic Weisbecker authored
    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: default avatarFrederic 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: default avatarIngo Molnar <mingo@elte.hu>
    dc8f6d89
super.c 62.4 KB